mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Refactoring. JavascriptBuilder becomes TeaVM and goes to org.teavm.vm
package, as well as some other classes go to org.teavm.vm.spi. html4j now supports generation of JavaScript that is completely compatible with bck2brwsr without altering HTML page
This commit is contained in:
parent
a1565015c8
commit
226f4c2c8a
|
@ -15,19 +15,19 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.classlib.impl;
|
package org.teavm.classlib.impl;
|
||||||
|
|
||||||
import org.teavm.javascript.JavascriptBuilderHost;
|
|
||||||
import org.teavm.javascript.JavascriptBuilderPlugin;
|
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
|
import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class JCLPlugin implements JavascriptBuilderPlugin {
|
public class JCLPlugin implements TeaVMPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void install(JavascriptBuilderHost host) {
|
public void install(TeaVMHost host) {
|
||||||
host.add(new EnumDependencySupport());
|
host.add(new EnumDependencySupport());
|
||||||
host.add(new EnumTransformer());
|
host.add(new EnumTransformer());
|
||||||
host.add(new ClassLookupDependencySupport());
|
host.add(new ClassLookupDependencySupport());
|
||||||
|
|
|
@ -33,7 +33,7 @@ import org.teavm.model.*;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class Renderer implements ExprVisitor, StatementVisitor {
|
public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext {
|
||||||
private static final String variableNames = "abcdefghijkmnopqrstuvwxyz";
|
private static final String variableNames = "abcdefghijkmnopqrstuvwxyz";
|
||||||
private NamingStrategy naming;
|
private NamingStrategy naming;
|
||||||
private SourceWriter writer;
|
private SourceWriter writer;
|
||||||
|
@ -57,14 +57,17 @@ public class Renderer implements ExprVisitor, StatementVisitor {
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public SourceWriter getWriter() {
|
public SourceWriter getWriter() {
|
||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public NamingStrategy getNaming() {
|
public NamingStrategy getNaming() {
|
||||||
return naming;
|
return naming;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isMinifying() {
|
public boolean isMinifying() {
|
||||||
return minifying;
|
return minifying;
|
||||||
}
|
}
|
||||||
|
@ -73,6 +76,16 @@ public class Renderer implements ExprVisitor, StatementVisitor {
|
||||||
this.minifying = minifying;
|
this.minifying = minifying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListableClassHolderSource getClassSource() {
|
||||||
|
return classSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassLoader getClassLoader() {
|
||||||
|
return classLoader;
|
||||||
|
}
|
||||||
|
|
||||||
public void renderRuntime() throws RenderingException {
|
public void renderRuntime() throws RenderingException {
|
||||||
try {
|
try {
|
||||||
renderRuntimeCls();
|
renderRuntimeCls();
|
||||||
|
|
|
@ -15,12 +15,22 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.javascript;
|
||||||
|
|
||||||
import java.io.IOException;
|
import org.teavm.codegen.NamingStrategy;
|
||||||
|
import org.teavm.codegen.SourceWriter;
|
||||||
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public interface JavascriptResourceRenderer {
|
public interface RenderingContext {
|
||||||
void render(JavascriptBuildTarget buildTarget) throws IOException;
|
NamingStrategy getNaming();
|
||||||
|
|
||||||
|
SourceWriter getWriter();
|
||||||
|
|
||||||
|
boolean isMinifying();
|
||||||
|
|
||||||
|
ListableClassReaderSource getClassSource();
|
||||||
|
|
||||||
|
ClassLoader getClassLoader();
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.vm;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -22,6 +22,6 @@ import java.io.OutputStream;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public interface JavascriptBuildTarget {
|
public interface BuildTarget {
|
||||||
OutputStream createResource(String fileName) throws IOException;
|
OutputStream createResource(String fileName) throws IOException;
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.vm;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
@ -24,7 +24,7 @@ import java.io.OutputStream;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class DirectoryBuildTarget implements JavascriptBuildTarget {
|
public class DirectoryBuildTarget implements BuildTarget {
|
||||||
private File directory;
|
private File directory;
|
||||||
|
|
||||||
public DirectoryBuildTarget(File directory) {
|
public DirectoryBuildTarget(File directory) {
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.vm;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -13,13 +13,14 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.vm;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.teavm.codegen.*;
|
import org.teavm.codegen.*;
|
||||||
import org.teavm.common.FiniteExecutor;
|
import org.teavm.common.FiniteExecutor;
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.*;
|
||||||
|
import org.teavm.javascript.*;
|
||||||
import org.teavm.javascript.ast.ClassNode;
|
import org.teavm.javascript.ast.ClassNode;
|
||||||
import org.teavm.javascript.ni.Generator;
|
import org.teavm.javascript.ni.Generator;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
|
@ -28,12 +29,15 @@ import org.teavm.model.util.ProgramUtils;
|
||||||
import org.teavm.model.util.RegisterAllocator;
|
import org.teavm.model.util.RegisterAllocator;
|
||||||
import org.teavm.optimization.ClassSetOptimizer;
|
import org.teavm.optimization.ClassSetOptimizer;
|
||||||
import org.teavm.optimization.Devirtualization;
|
import org.teavm.optimization.Devirtualization;
|
||||||
|
import org.teavm.vm.spi.RendererListener;
|
||||||
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
|
import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class JavascriptBuilder implements JavascriptBuilderHost {
|
public class TeaVM implements TeaVMHost {
|
||||||
private JavascriptProcessedClassSource classSource;
|
private JavascriptProcessedClassSource classSource;
|
||||||
private DependencyChecker dependencyChecker;
|
private DependencyChecker dependencyChecker;
|
||||||
private FiniteExecutor executor;
|
private FiniteExecutor executor;
|
||||||
|
@ -41,12 +45,13 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
|
||||||
private boolean minifying = true;
|
private boolean minifying = true;
|
||||||
private boolean bytecodeLogging;
|
private boolean bytecodeLogging;
|
||||||
private OutputStream logStream = System.out;
|
private OutputStream logStream = System.out;
|
||||||
private Map<String, JavascriptEntryPoint> entryPoints = new HashMap<>();
|
private Map<String, TeaVMEntryPoint> entryPoints = new HashMap<>();
|
||||||
private Map<String, String> exportedClasses = new HashMap<>();
|
private Map<String, String> exportedClasses = new HashMap<>();
|
||||||
private List<JavascriptResourceRenderer> ressourceRenderers = new ArrayList<>();
|
|
||||||
private Map<MethodReference, Generator> methodGenerators = new HashMap<>();
|
private Map<MethodReference, Generator> methodGenerators = new HashMap<>();
|
||||||
|
private List<RendererListener> rendererListeners = new ArrayList<>();
|
||||||
|
private Properties properties = new Properties();
|
||||||
|
|
||||||
JavascriptBuilder(ClassHolderSource classSource, ClassLoader classLoader, FiniteExecutor executor) {
|
TeaVM(ClassHolderSource classSource, ClassLoader classLoader, FiniteExecutor executor) {
|
||||||
this.classSource = new JavascriptProcessedClassSource(classSource);
|
this.classSource = new JavascriptProcessedClassSource(classSource);
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
dependencyChecker = new DependencyChecker(this.classSource, classLoader, executor);
|
dependencyChecker = new DependencyChecker(this.classSource, classLoader, executor);
|
||||||
|
@ -63,16 +68,17 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
|
||||||
classSource.addTransformer(transformer);
|
classSource.addTransformer(transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(JavascriptResourceRenderer resourceRenderer) {
|
|
||||||
ressourceRenderers.add(resourceRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(MethodReference methodRef, Generator generator) {
|
public void add(MethodReference methodRef, Generator generator) {
|
||||||
methodGenerators.put(methodRef, generator);
|
methodGenerators.put(methodRef, generator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(RendererListener listener) {
|
||||||
|
rendererListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
|
@ -94,18 +100,37 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
|
||||||
this.bytecodeLogging = bytecodeLogging;
|
this.bytecodeLogging = bytecodeLogging;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavascriptEntryPoint entryPoint(String name, MethodReference ref) {
|
public void setProperties(Properties properties) {
|
||||||
|
this.properties.clear();
|
||||||
|
if (properties != null) {
|
||||||
|
this.properties.putAll(properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Properties getProperties() {
|
||||||
|
return new Properties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TeaVMEntryPoint entryPoint(String name, MethodReference ref) {
|
||||||
if (entryPoints.containsKey(name)) {
|
if (entryPoints.containsKey(name)) {
|
||||||
throw new IllegalArgumentException("Entry point with public name `" + name + "' already defined " +
|
throw new IllegalArgumentException("Entry point with public name `" + name + "' already defined " +
|
||||||
"for method " + ref);
|
"for method " + ref);
|
||||||
}
|
}
|
||||||
JavascriptEntryPoint entryPoint = new JavascriptEntryPoint(name, ref,
|
TeaVMEntryPoint entryPoint = new TeaVMEntryPoint(name, ref,
|
||||||
dependencyChecker.linkMethod(ref, DependencyStack.ROOT));
|
dependencyChecker.linkMethod(ref, DependencyStack.ROOT));
|
||||||
dependencyChecker.initClass(ref.getClassName(), DependencyStack.ROOT);
|
dependencyChecker.initClass(ref.getClassName(), DependencyStack.ROOT);
|
||||||
entryPoints.put(name, entryPoint);
|
entryPoints.put(name, entryPoint);
|
||||||
return entryPoint;
|
return entryPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TeaVMEntryPoint linkMethod(MethodReference ref) {
|
||||||
|
TeaVMEntryPoint entryPoint = new TeaVMEntryPoint("", ref,
|
||||||
|
dependencyChecker.linkMethod(ref, DependencyStack.ROOT));
|
||||||
|
dependencyChecker.initClass(ref.getClassName(), DependencyStack.ROOT);
|
||||||
|
return entryPoint;
|
||||||
|
}
|
||||||
|
|
||||||
public void exportType(String name, String className) {
|
public void exportType(String name, String className) {
|
||||||
if (exportedClasses.containsKey(name)) {
|
if (exportedClasses.containsKey(name)) {
|
||||||
throw new IllegalArgumentException("Class with public name `" + name + "' already defined for class " +
|
throw new IllegalArgumentException("Class with public name `" + name + "' already defined for class " +
|
||||||
|
@ -115,6 +140,10 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
|
||||||
exportedClasses.put(name, className);
|
exportedClasses.put(name, className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void linkType(String className) {
|
||||||
|
dependencyChecker.initClass(className, DependencyStack.ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
public ClassHolderSource getClassSource() {
|
public ClassHolderSource getClassSource() {
|
||||||
return classSource;
|
return classSource;
|
||||||
}
|
}
|
||||||
|
@ -135,7 +164,7 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
|
||||||
dependencyChecker.checkForMissingItems();
|
dependencyChecker.checkForMissingItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void build(Appendable writer, JavascriptBuildTarget target) throws RenderingException {
|
public void build(Appendable writer, BuildTarget target) throws RenderingException {
|
||||||
AliasProvider aliasProvider = minifying ? new MinifyingAliasProvider() : new DefaultAliasProvider();
|
AliasProvider aliasProvider = minifying ? new MinifyingAliasProvider() : new DefaultAliasProvider();
|
||||||
DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, classSource);
|
DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, classSource);
|
||||||
naming.setMinifying(minifying);
|
naming.setMinifying(minifying);
|
||||||
|
@ -174,17 +203,27 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
|
||||||
// Just don't do anything
|
// Just don't do anything
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Renderer renderer = new Renderer(sourceWriter, classSet, classLoader);
|
|
||||||
renderer.renderRuntime();
|
|
||||||
for (Map.Entry<MethodReference, Generator> entry : methodGenerators.entrySet()) {
|
for (Map.Entry<MethodReference, Generator> entry : methodGenerators.entrySet()) {
|
||||||
decompiler.addGenerator(entry.getKey(), entry.getValue());
|
decompiler.addGenerator(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
List<ClassNode> clsNodes = decompiler.decompile(classSet.getClassNames());
|
List<ClassNode> clsNodes = decompiler.decompile(classSet.getClassNames());
|
||||||
for (ClassNode clsNode : clsNodes) {
|
Renderer renderer = new Renderer(sourceWriter, classSet, classLoader);
|
||||||
renderer.render(clsNode);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
for (Map.Entry<String, JavascriptEntryPoint> entry : entryPoints.entrySet()) {
|
for (RendererListener listener : rendererListeners) {
|
||||||
|
listener.begin(renderer, target);
|
||||||
|
}
|
||||||
|
renderer.renderRuntime();
|
||||||
|
for (ClassNode clsNode : clsNodes) {
|
||||||
|
ClassReader cls = classSet.get(clsNode.getName());
|
||||||
|
for (RendererListener listener : rendererListeners) {
|
||||||
|
listener.beforeClass(cls);
|
||||||
|
}
|
||||||
|
renderer.render(clsNode);
|
||||||
|
for (RendererListener listener : rendererListeners) {
|
||||||
|
listener.afterClass(cls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, TeaVMEntryPoint> entry : entryPoints.entrySet()) {
|
||||||
sourceWriter.append(entry.getKey()).ws().append("=").ws().appendMethodBody(entry.getValue().reference)
|
sourceWriter.append(entry.getKey()).ws().append("=").ws().appendMethodBody(entry.getValue().reference)
|
||||||
.append(";").softNewLine();
|
.append(";").softNewLine();
|
||||||
}
|
}
|
||||||
|
@ -192,8 +231,8 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
|
||||||
sourceWriter.append(entry.getKey()).ws().append("=").ws().appendClass(entry.getValue()).append(";")
|
sourceWriter.append(entry.getKey()).ws().append("=").ws().appendClass(entry.getValue()).append(";")
|
||||||
.softNewLine();
|
.softNewLine();
|
||||||
}
|
}
|
||||||
for (JavascriptResourceRenderer resourceRenderer : ressourceRenderers) {
|
for (RendererListener listener : rendererListeners) {
|
||||||
resourceRenderer.render(target);
|
listener.complete();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RenderingException("IO Error occured", e);
|
throw new RenderingException("IO Error occured", e);
|
||||||
|
@ -350,7 +389,7 @@ public class JavascriptBuilder implements JavascriptBuilderHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void installPlugins() {
|
public void installPlugins() {
|
||||||
for (JavascriptBuilderPlugin plugin : ServiceLoader.load(JavascriptBuilderPlugin.class, classLoader)) {
|
for (TeaVMPlugin plugin : ServiceLoader.load(TeaVMPlugin.class, classLoader)) {
|
||||||
plugin.install(this);
|
plugin.install(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.vm;
|
||||||
|
|
||||||
import org.teavm.common.FiniteExecutor;
|
import org.teavm.common.FiniteExecutor;
|
||||||
import org.teavm.common.SimpleFiniteExecutor;
|
import org.teavm.common.SimpleFiniteExecutor;
|
||||||
|
@ -23,7 +23,7 @@ import org.teavm.model.ClassHolderSource;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class JavascriptBuilderFactory {
|
public class TeaVMBuilder {
|
||||||
ClassHolderSource classSource;
|
ClassHolderSource classSource;
|
||||||
ClassLoader classLoader;
|
ClassLoader classLoader;
|
||||||
FiniteExecutor executor = new SimpleFiniteExecutor();
|
FiniteExecutor executor = new SimpleFiniteExecutor();
|
||||||
|
@ -32,27 +32,30 @@ public class JavascriptBuilderFactory {
|
||||||
return classSource;
|
return classSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClassSource(ClassHolderSource classSource) {
|
public TeaVMBuilder setClassSource(ClassHolderSource classSource) {
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClassLoader(ClassLoader classLoader) {
|
public TeaVMBuilder setClassLoader(ClassLoader classLoader) {
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FiniteExecutor getExecutor() {
|
public FiniteExecutor getExecutor() {
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExecutor(FiniteExecutor executor) {
|
public TeaVMBuilder setExecutor(FiniteExecutor executor) {
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavascriptBuilder create() {
|
public TeaVM build() {
|
||||||
return new JavascriptBuilder(classSource, classLoader, executor);
|
return new TeaVM(classSource, classLoader, executor);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.vm;
|
||||||
|
|
||||||
import org.teavm.dependency.MethodDependency;
|
import org.teavm.dependency.MethodDependency;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
@ -22,12 +22,12 @@ import org.teavm.model.MethodReference;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class JavascriptEntryPoint {
|
public class TeaVMEntryPoint {
|
||||||
private String publicName;
|
private String publicName;
|
||||||
MethodReference reference;
|
MethodReference reference;
|
||||||
private MethodDependency method;
|
private MethodDependency method;
|
||||||
|
|
||||||
JavascriptEntryPoint(String publicName, MethodReference reference, MethodDependency method) {
|
TeaVMEntryPoint(String publicName, MethodReference reference, MethodDependency method) {
|
||||||
this.publicName = publicName;
|
this.publicName = publicName;
|
||||||
this.reference = reference;
|
this.reference = reference;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
|
@ -38,7 +38,7 @@ public class JavascriptEntryPoint {
|
||||||
return publicName;
|
return publicName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavascriptEntryPoint withValue(int argument, String type) {
|
public TeaVMEntryPoint withValue(int argument, String type) {
|
||||||
if (argument > reference.parameterCount()) {
|
if (argument > reference.parameterCount()) {
|
||||||
throw new IllegalArgumentException("Illegal argument #" + argument + " of " + reference.parameterCount());
|
throw new IllegalArgumentException("Illegal argument #" + argument + " of " + reference.parameterCount());
|
||||||
}
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 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.vm.spi;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.teavm.javascript.RenderingContext;
|
||||||
|
import org.teavm.model.ClassReader;
|
||||||
|
import org.teavm.vm.BuildTarget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractRendererListener implements RendererListener {
|
||||||
|
@Override
|
||||||
|
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeClass(ClassReader cls) throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterClass(ClassReader cls) throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void complete() throws IOException {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 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.vm.spi;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.teavm.javascript.RenderingContext;
|
||||||
|
import org.teavm.model.ClassReader;
|
||||||
|
import org.teavm.vm.BuildTarget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public interface RendererListener {
|
||||||
|
void begin(RenderingContext context, BuildTarget buildTarget) throws IOException;
|
||||||
|
|
||||||
|
void beforeClass(ClassReader cls) throws IOException;
|
||||||
|
|
||||||
|
void afterClass(ClassReader cls) throws IOException;
|
||||||
|
|
||||||
|
void complete() throws IOException;
|
||||||
|
}
|
|
@ -13,8 +13,9 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.vm.spi;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
import org.teavm.dependency.DependencyListener;
|
import org.teavm.dependency.DependencyListener;
|
||||||
import org.teavm.javascript.ni.Generator;
|
import org.teavm.javascript.ni.Generator;
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
|
@ -24,14 +25,16 @@ import org.teavm.model.MethodReference;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public interface JavascriptBuilderHost {
|
public interface TeaVMHost {
|
||||||
void add(DependencyListener dependencyListener);
|
void add(DependencyListener dependencyListener);
|
||||||
|
|
||||||
void add(ClassHolderTransformer classTransformer);
|
void add(ClassHolderTransformer classTransformer);
|
||||||
|
|
||||||
void add(JavascriptResourceRenderer resourceRenderer);
|
|
||||||
|
|
||||||
void add(MethodReference methodRef, Generator generator);
|
void add(MethodReference methodRef, Generator generator);
|
||||||
|
|
||||||
|
void add(RendererListener listener);
|
||||||
|
|
||||||
ClassLoader getClassLoader();
|
ClassLoader getClassLoader();
|
||||||
|
|
||||||
|
Properties getProperties();
|
||||||
}
|
}
|
|
@ -13,12 +13,12 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.vm.spi;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public interface JavascriptBuilderPlugin {
|
public interface TeaVMPlugin {
|
||||||
void install(JavascriptBuilderHost host);
|
void install(TeaVMHost host);
|
||||||
}
|
}
|
|
@ -99,9 +99,6 @@
|
||||||
<transformers>
|
<transformers>
|
||||||
<param>org.teavm.javascript.NullPointerExceptionTransformer</param>
|
<param>org.teavm.javascript.NullPointerExceptionTransformer</param>
|
||||||
</transformers>
|
</transformers>
|
||||||
<additionalScripts>
|
|
||||||
<param>org/netbeans/html/ko4j/knockout-2.2.1.js</param>
|
|
||||||
</additionalScripts>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 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 java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.teavm.codegen.SourceWriter;
|
||||||
|
import org.teavm.dependency.*;
|
||||||
|
import org.teavm.javascript.Renderer;
|
||||||
|
import org.teavm.javascript.RenderingContext;
|
||||||
|
import org.teavm.vm.BuildTarget;
|
||||||
|
import org.teavm.vm.spi.AbstractRendererListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public class EntryPointGenerator extends AbstractRendererListener implements DependencyListener {
|
||||||
|
private List<String> classesToLoad = new ArrayList<>();
|
||||||
|
private SourceWriter writer;
|
||||||
|
|
||||||
|
public EntryPointGenerator(String classesToLoad) {
|
||||||
|
for (String className : classesToLoad.split(",| |;")) {
|
||||||
|
className = className.trim();
|
||||||
|
if (!className.isEmpty()) {
|
||||||
|
this.classesToLoad.add(className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
|
||||||
|
writer = context.getWriter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void complete() throws IOException {
|
||||||
|
if (classesToLoad.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
writer.append("function VM() {").softNewLine();
|
||||||
|
writer.append("}").newLine();
|
||||||
|
writer.append("VM.prototype.loadClass = function(className) {").softNewLine().indent();
|
||||||
|
writer.append("switch (className) {").indent().softNewLine();
|
||||||
|
for (String className : classesToLoad) {
|
||||||
|
writer.append("case \"").append(Renderer.escapeString(className)).append("\": ");
|
||||||
|
writer.appendClass(className).append(".$clinit(); break;").softNewLine();
|
||||||
|
}
|
||||||
|
writer.append("default: throw \"Can't load class \" + className;").softNewLine();
|
||||||
|
writer.outdent().append("}").softNewLine();
|
||||||
|
writer.outdent().append("}").newLine();
|
||||||
|
writer.append("function bck2brwsr() { return new VM(); }").newLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void started(DependencyChecker dependencyChecker) {
|
||||||
|
for (String className : classesToLoad) {
|
||||||
|
dependencyChecker.initClass(className, DependencyStack.ROOT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void classAchieved(DependencyChecker dependencyChecker, String className) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void methodAchieved(DependencyChecker dependencyChecker, MethodDependency method) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fieldAchieved(DependencyChecker dependencyChecker, FieldDependency field) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,18 +15,25 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.html4j;
|
package org.teavm.html4j;
|
||||||
|
|
||||||
import org.teavm.javascript.JavascriptBuilderHost;
|
import org.teavm.dependency.DependencyListener;
|
||||||
import org.teavm.javascript.JavascriptBuilderPlugin;
|
import org.teavm.vm.spi.RendererListener;
|
||||||
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
|
import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class HTML4JPlugin implements JavascriptBuilderPlugin {
|
public class HTML4JPlugin implements TeaVMPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void install(JavascriptBuilderHost host) {
|
public void install(TeaVMHost host) {
|
||||||
host.add(new JavaScriptBodyDependency());
|
host.add(new JavaScriptBodyDependency());
|
||||||
host.add(new JavaScriptBodyTransformer());
|
host.add(new JavaScriptBodyTransformer());
|
||||||
host.add(new JCLHacks());
|
host.add(new JCLHacks());
|
||||||
|
host.add(new JavaScriptResourceInterceptor());
|
||||||
|
EntryPointGenerator entryPointGen = new EntryPointGenerator(host.getProperties()
|
||||||
|
.getProperty("html4j.entryPoints", ""));
|
||||||
|
host.add((DependencyListener)entryPointGen);
|
||||||
|
host.add((RendererListener)entryPointGen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 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 java.io.InputStream;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import net.java.html.js.JavaScriptResource;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.teavm.javascript.RenderingContext;
|
||||||
|
import org.teavm.javascript.RenderingException;
|
||||||
|
import org.teavm.model.AnnotationReader;
|
||||||
|
import org.teavm.model.ClassReader;
|
||||||
|
import org.teavm.vm.BuildTarget;
|
||||||
|
import org.teavm.vm.spi.AbstractRendererListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public class JavaScriptResourceInterceptor extends AbstractRendererListener {
|
||||||
|
@Override
|
||||||
|
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
|
||||||
|
boolean hasOneResource = false;
|
||||||
|
for (String className : context.getClassSource().getClassNames()) {
|
||||||
|
ClassReader cls = context.getClassSource().get(className);
|
||||||
|
AnnotationReader annot = cls.getAnnotations().get(JavaScriptResource.class.getName());
|
||||||
|
if (annot == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String path = annot.getValue("value").getString();
|
||||||
|
String packageName = className.substring(0, className.lastIndexOf('.'));
|
||||||
|
String resourceName = packageName.replace('.', '/') + "/" + path;
|
||||||
|
try (InputStream input = context.getClassLoader().getResourceAsStream(resourceName)) {
|
||||||
|
if (input == null) {
|
||||||
|
throw new RenderingException("Error processing JavaScriptResource annotation on class " +
|
||||||
|
className + ". Resource not found: " + resourceName);
|
||||||
|
}
|
||||||
|
@SuppressWarnings("resource")
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
IOUtils.copy(input, writer);
|
||||||
|
writer.close();
|
||||||
|
context.getWriter().append("// Resource " + path + " included by " + className).newLine();
|
||||||
|
context.getWriter().append(writer.toString()).newLine().newLine();
|
||||||
|
}
|
||||||
|
hasOneResource = true;
|
||||||
|
}
|
||||||
|
if (hasOneResource) {
|
||||||
|
context.getWriter().append("// TeaVM generated classes").newLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,16 +15,16 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript.ni.plugin;
|
package org.teavm.javascript.ni.plugin;
|
||||||
|
|
||||||
import org.teavm.javascript.JavascriptBuilderHost;
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
import org.teavm.javascript.JavascriptBuilderPlugin;
|
import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class JSObjectBuilderPlugin implements JavascriptBuilderPlugin {
|
public class JSObjectBuilderPlugin implements TeaVMPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void install(JavascriptBuilderHost host) {
|
public void install(TeaVMHost host) {
|
||||||
host.add(new JSObjectClassTransformer());
|
host.add(new JSObjectClassTransformer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,14 +33,17 @@ import org.apache.maven.plugins.annotations.Parameter;
|
||||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||||
import org.apache.maven.project.MavenProject;
|
import org.apache.maven.project.MavenProject;
|
||||||
import org.teavm.common.ThreadPoolFiniteExecutor;
|
import org.teavm.common.ThreadPoolFiniteExecutor;
|
||||||
import org.teavm.javascript.DirectoryBuildTarget;
|
import org.teavm.javascript.RenderingContext;
|
||||||
import org.teavm.javascript.JavascriptBuilder;
|
|
||||||
import org.teavm.javascript.JavascriptBuilderFactory;
|
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||||
|
import org.teavm.vm.BuildTarget;
|
||||||
|
import org.teavm.vm.DirectoryBuildTarget;
|
||||||
|
import org.teavm.vm.TeaVM;
|
||||||
|
import org.teavm.vm.TeaVMBuilder;
|
||||||
|
import org.teavm.vm.spi.AbstractRendererListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -61,6 +64,7 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
||||||
private File classFiles;
|
private File classFiles;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
private String targetFileName = "classes.js";
|
private String targetFileName = "classes.js";
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
|
@ -72,6 +76,9 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
@Parameter
|
@Parameter
|
||||||
private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE;
|
private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private Properties properties;
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private boolean mainPageIncluded;
|
private boolean mainPageIncluded;
|
||||||
|
|
||||||
|
@ -92,6 +99,10 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
this.targetDirectory = targetDirectory;
|
this.targetDirectory = targetDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTargetFileName(String targetFileName) {
|
||||||
|
this.targetFileName = targetFileName;
|
||||||
|
}
|
||||||
|
|
||||||
public void setClassFiles(File classFiles) {
|
public void setClassFiles(File classFiles) {
|
||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
}
|
}
|
||||||
|
@ -124,6 +135,10 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
this.transformers = transformers;
|
this.transformers = transformers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProperties(Properties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws MojoExecutionException {
|
public void execute() throws MojoExecutionException {
|
||||||
Log log = getLog();
|
Log log = getLog();
|
||||||
|
@ -131,9 +146,8 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
try {
|
try {
|
||||||
ClassLoader classLoader = prepareClassLoader();
|
ClassLoader classLoader = prepareClassLoader();
|
||||||
log.info("Building JavaScript file");
|
log.info("Building JavaScript file");
|
||||||
JavascriptBuilderFactory builderFactory = new JavascriptBuilderFactory();
|
TeaVMBuilder vmBuilder = new TeaVMBuilder();
|
||||||
builderFactory.setClassLoader(classLoader);
|
vmBuilder.setClassLoader(classLoader).setClassSource(new ClasspathClassHolderSource(classLoader));
|
||||||
builderFactory.setClassSource(new ClasspathClassHolderSource(classLoader));
|
|
||||||
if (numThreads != 1) {
|
if (numThreads != 1) {
|
||||||
int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors();
|
int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors();
|
||||||
final ThreadPoolFiniteExecutor executor = new ThreadPoolFiniteExecutor(threads);
|
final ThreadPoolFiniteExecutor executor = new ThreadPoolFiniteExecutor(threads);
|
||||||
|
@ -142,28 +156,30 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
executor.stop();
|
executor.stop();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
builderFactory.setExecutor(executor);
|
vmBuilder.setExecutor(executor);
|
||||||
}
|
}
|
||||||
JavascriptBuilder builder = builderFactory.create();
|
TeaVM vm = vmBuilder.build();
|
||||||
builder.setMinifying(minifying);
|
vm.setMinifying(minifying);
|
||||||
builder.setBytecodeLogging(bytecodeLogging);
|
vm.setBytecodeLogging(bytecodeLogging);
|
||||||
builder.installPlugins();
|
vm.setProperties(properties);
|
||||||
|
vm.installPlugins();
|
||||||
for (ClassHolderTransformer transformer : instantiateTransformers(classLoader)) {
|
for (ClassHolderTransformer transformer : instantiateTransformers(classLoader)) {
|
||||||
builder.add(transformer);
|
vm.add(transformer);
|
||||||
|
}
|
||||||
|
vm.prepare();
|
||||||
|
if (mainClass != null) {
|
||||||
|
MethodDescriptor mainMethodDesc = new MethodDescriptor("main", ValueType.arrayOf(
|
||||||
|
ValueType.object("java.lang.String")), ValueType.VOID);
|
||||||
|
vm.entryPoint("main", new MethodReference(mainClass, mainMethodDesc))
|
||||||
|
.withValue(1, "java.lang.String");
|
||||||
}
|
}
|
||||||
builder.prepare();
|
|
||||||
MethodDescriptor mainMethodDesc = new MethodDescriptor("main", ValueType.arrayOf(
|
|
||||||
ValueType.object("java.lang.String")), ValueType.VOID);
|
|
||||||
builder.entryPoint("main", new MethodReference(mainClass, mainMethodDesc))
|
|
||||||
.withValue(1, "java.lang.String");
|
|
||||||
targetDirectory.mkdirs();
|
targetDirectory.mkdirs();
|
||||||
try (FileWriter writer = new FileWriter(new File(targetDirectory, targetFileName))) {
|
try (FileWriter writer = new FileWriter(new File(targetDirectory, targetFileName))) {
|
||||||
if (runtime == RuntimeCopyOperation.MERGED) {
|
if (runtime == RuntimeCopyOperation.MERGED) {
|
||||||
resourceToWriter("org/teavm/javascript/runtime.js", writer);
|
vm.add(runtimeInjector);
|
||||||
writer.append("\n");
|
|
||||||
}
|
}
|
||||||
builder.build(writer, new DirectoryBuildTarget(targetDirectory));
|
vm.build(writer, new DirectoryBuildTarget(targetDirectory));
|
||||||
builder.checkForMissingItems();
|
vm.checkForMissingItems();
|
||||||
log.info("JavaScript file successfully built");
|
log.info("JavaScript file successfully built");
|
||||||
}
|
}
|
||||||
if (runtime == RuntimeCopyOperation.SEPARATE) {
|
if (runtime == RuntimeCopyOperation.SEPARATE) {
|
||||||
|
@ -191,6 +207,17 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AbstractRendererListener runtimeInjector = new AbstractRendererListener() {
|
||||||
|
@Override
|
||||||
|
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
|
||||||
|
@SuppressWarnings("resource")
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
resourceToWriter("org/teavm/javascript/runtime.js", writer);
|
||||||
|
writer.close();
|
||||||
|
context.getWriter().append(writer.toString()).newLine();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private List<ClassHolderTransformer> instantiateTransformers(ClassLoader classLoader)
|
private List<ClassHolderTransformer> instantiateTransformers(ClassLoader classLoader)
|
||||||
throws MojoExecutionException {
|
throws MojoExecutionException {
|
||||||
List<ClassHolderTransformer> transformerInstances = new ArrayList<>();
|
List<ClassHolderTransformer> transformerInstances = new ArrayList<>();
|
||||||
|
|
|
@ -39,13 +39,13 @@ import org.apache.maven.project.MavenProject;
|
||||||
import org.teavm.common.FiniteExecutor;
|
import org.teavm.common.FiniteExecutor;
|
||||||
import org.teavm.common.SimpleFiniteExecutor;
|
import org.teavm.common.SimpleFiniteExecutor;
|
||||||
import org.teavm.common.ThreadPoolFiniteExecutor;
|
import org.teavm.common.ThreadPoolFiniteExecutor;
|
||||||
import org.teavm.javascript.DirectoryBuildTarget;
|
|
||||||
import org.teavm.javascript.JavascriptBuilder;
|
|
||||||
import org.teavm.javascript.JavascriptBuilderFactory;
|
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||||
import org.teavm.testing.JUnitTestAdapter;
|
import org.teavm.testing.JUnitTestAdapter;
|
||||||
import org.teavm.testing.TestAdapter;
|
import org.teavm.testing.TestAdapter;
|
||||||
|
import org.teavm.vm.DirectoryBuildTarget;
|
||||||
|
import org.teavm.vm.TeaVM;
|
||||||
|
import org.teavm.vm.TeaVMBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -311,33 +311,33 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
||||||
|
|
||||||
private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource,
|
private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource,
|
||||||
MethodReference methodRef, String targetName, FiniteExecutor executor) throws IOException {
|
MethodReference methodRef, String targetName, FiniteExecutor executor) throws IOException {
|
||||||
JavascriptBuilderFactory builderFactory = new JavascriptBuilderFactory();
|
TeaVM vm = new TeaVMBuilder()
|
||||||
builderFactory.setClassLoader(classLoader);
|
.setClassLoader(classLoader)
|
||||||
builderFactory.setClassSource(classSource);
|
.setClassSource(classSource)
|
||||||
builderFactory.setExecutor(executor);
|
.setExecutor(executor)
|
||||||
JavascriptBuilder builder = builderFactory.create();
|
.build();
|
||||||
builder.setMinifying(minifying);
|
vm.setMinifying(minifying);
|
||||||
builder.installPlugins();
|
vm.installPlugins();
|
||||||
for (ClassHolderTransformer transformer : transformerInstances) {
|
for (ClassHolderTransformer transformer : transformerInstances) {
|
||||||
builder.add(transformer);
|
vm.add(transformer);
|
||||||
}
|
}
|
||||||
builder.prepare();
|
vm.prepare();
|
||||||
File file = new File(outputDir, targetName);
|
File file = new File(outputDir, targetName);
|
||||||
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
||||||
MethodReference cons = new MethodReference(methodRef.getClassName(),
|
MethodReference cons = new MethodReference(methodRef.getClassName(),
|
||||||
new MethodDescriptor("<init>", ValueType.VOID));
|
new MethodDescriptor("<init>", ValueType.VOID));
|
||||||
builder.entryPoint("initInstance", cons);
|
vm.entryPoint("initInstance", cons);
|
||||||
builder.entryPoint("runTest", methodRef).withValue(0, cons.getClassName());
|
vm.entryPoint("runTest", methodRef).withValue(0, cons.getClassName());
|
||||||
builder.exportType("TestClass", cons.getClassName());
|
vm.exportType("TestClass", cons.getClassName());
|
||||||
builder.build(innerWriter, new DirectoryBuildTarget(outputDir));
|
vm.build(innerWriter, new DirectoryBuildTarget(outputDir));
|
||||||
if (!builder.hasMissingItems()) {
|
if (!vm.hasMissingItems()) {
|
||||||
innerWriter.append("\n");
|
innerWriter.append("\n");
|
||||||
innerWriter.append("\nJUnitClient.run();");
|
innerWriter.append("\nJUnitClient.run();");
|
||||||
innerWriter.close();
|
innerWriter.close();
|
||||||
} else {
|
} else {
|
||||||
innerWriter.append("JUnitClient.reportError(\n");
|
innerWriter.append("JUnitClient.reportError(\n");
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
builder.showMissingItems(sb);
|
vm.showMissingItems(sb);
|
||||||
escapeStringLiteral(sb.toString(), innerWriter);
|
escapeStringLiteral(sb.toString(), innerWriter);
|
||||||
innerWriter.append(");");
|
innerWriter.append(");");
|
||||||
getLog().warn("Error building test " + methodRef);
|
getLog().warn("Error building test " + methodRef);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user