mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-02 21:34:11 -08:00
Refactor TeaVM to support pluggable targets like JavaScript, WebAssembly, LLVM, etc (with only JavaScript target for now)
This commit is contained in:
parent
1f30e5fd88
commit
52ace0c252
|
@ -24,15 +24,12 @@ import java.util.ServiceLoader;
|
|||
import org.teavm.classlib.impl.lambda.LambdaMetafactorySubstitutor;
|
||||
import org.teavm.classlib.impl.unicode.CLDRReader;
|
||||
import org.teavm.classlib.java.lang.reflect.AnnotationDependencyListener;
|
||||
import org.teavm.javascript.target.TeaVMJavaScriptHost;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.platform.PlatformClass;
|
||||
import org.teavm.vm.spi.TeaVMHost;
|
||||
import org.teavm.vm.spi.TeaVMPlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class JCLPlugin implements TeaVMPlugin {
|
||||
@Override
|
||||
public void install(TeaVMHost host) {
|
||||
|
@ -40,7 +37,11 @@ public class JCLPlugin implements TeaVMPlugin {
|
|||
host.add(serviceLoaderSupp);
|
||||
MethodReference loadServicesMethod = new MethodReference(ServiceLoader.class, "loadServices",
|
||||
PlatformClass.class, Object[].class);
|
||||
host.add(loadServicesMethod, serviceLoaderSupp);
|
||||
TeaVMJavaScriptHost jsExtension = host.getExtension(TeaVMJavaScriptHost.class);
|
||||
if (jsExtension != null) {
|
||||
jsExtension.add(loadServicesMethod, serviceLoaderSupp);
|
||||
}
|
||||
|
||||
JavacSupport javacSupport = new JavacSupport();
|
||||
host.add(javacSupport);
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<property key="Bundle-Description" value="TeaVM Java class library emulation" />
|
||||
<property key="Export-Package" value="org.teavm.classlib.*" />
|
||||
<property key="Bundle-Name" value="TeaVM Java class library" />
|
||||
<property key="Include-Resource" value="html/jcl.html=$MODULE_DIR$/src/main/resources/html/jcl.html,html/annotation_obj.png=$MODULE_DIR$/src/main/resources/html/annotation_obj.png,html/enum_obj.png=$MODULE_DIR$/src/main/resources/html/enum_obj.png,html/jcl.css=$MODULE_DIR$/src/main/resources/html/jcl.css,html/package_obj.png=$MODULE_DIR$/src/main/resources/html/package_obj.png,html/field_public_obj.png=$MODULE_DIR$/src/main/resources/html/field_public_obj.png,html/class_obj.png=$MODULE_DIR$/src/main/resources/html/class_obj.png,html/int_obj.png=$MODULE_DIR$/src/main/resources/html/int_obj.png,html/jcl-class.html=$MODULE_DIR$/src/main/resources/html/jcl-class.html,html/methpro_obj.png=$MODULE_DIR$/src/main/resources/html/methpro_obj.png,html/methpub_obj.png=$MODULE_DIR$/src/main/resources/html/methpub_obj.png,html/field_protected_obj.png=$MODULE_DIR$/src/main/resources/html/field_protected_obj.png,META-INF/teavm.properties=$MODULE_DIR$/src/main/resources/META-INF/teavm.properties,META-INF/services/org.teavm.vm.spi.TeaVMPlugin=$MODULE_DIR$/src/main/resources/META-INF/services/org.teavm.vm.spi.TeaVMPlugin,org/teavm/classlib/impl/tz/tzdata2015d.zip=$MODULE_DIR$/src/main/resources/org/teavm/classlib/impl/tz/tzdata2015d.zip,org/teavm/classlib/impl/currency/iso4217.xml=$MODULE_DIR$/src/main/resources/org/teavm/classlib/impl/currency/iso4217.xml,org/teavm/classlib/impl/currency/iso3166.csv=$MODULE_DIR$/src/main/resources/org/teavm/classlib/impl/currency/iso3166.csv,org/teavm/classlib/impl/unicode/UnicodeData.txt=$MODULE_DIR$/src/main/resources/org/teavm/classlib/impl/unicode/UnicodeData.txt,org/teavm/classlib/impl/unicode/cldr-json.zip=$MODULE_DIR$/src/main/resources/org/teavm/classlib/impl/unicode/cldr-json.zip" />
|
||||
<property key="Include-Resource" value="org/teavm/classlib/impl/tz/tzdata2015d.zip=$MODULE_DIR$/src/main/resources/org/teavm/classlib/impl/tz/tzdata2015d.zip,org/teavm/classlib/impl/currency/iso3166.csv=$MODULE_DIR$/src/main/resources/org/teavm/classlib/impl/currency/iso3166.csv,org/teavm/classlib/impl/currency/iso4217.xml=$MODULE_DIR$/src/main/resources/org/teavm/classlib/impl/currency/iso4217.xml,org/teavm/classlib/impl/unicode/cldr-json.zip=$MODULE_DIR$/src/main/resources/org/teavm/classlib/impl/unicode/cldr-json.zip,org/teavm/classlib/impl/unicode/UnicodeData.txt=$MODULE_DIR$/src/main/resources/org/teavm/classlib/impl/unicode/UnicodeData.txt,html/methpro_obj.png=$MODULE_DIR$/src/main/resources/html/methpro_obj.png,html/enum_obj.png=$MODULE_DIR$/src/main/resources/html/enum_obj.png,html/class_obj.png=$MODULE_DIR$/src/main/resources/html/class_obj.png,html/annotation_obj.png=$MODULE_DIR$/src/main/resources/html/annotation_obj.png,html/methpub_obj.png=$MODULE_DIR$/src/main/resources/html/methpub_obj.png,html/jcl-class.html=$MODULE_DIR$/src/main/resources/html/jcl-class.html,html/package_obj.png=$MODULE_DIR$/src/main/resources/html/package_obj.png,html/field_public_obj.png=$MODULE_DIR$/src/main/resources/html/field_public_obj.png,html/jcl.html=$MODULE_DIR$/src/main/resources/html/jcl.html,html/jcl.css=$MODULE_DIR$/src/main/resources/html/jcl.css,html/field_protected_obj.png=$MODULE_DIR$/src/main/resources/html/field_protected_obj.png,html/int_obj.png=$MODULE_DIR$/src/main/resources/html/int_obj.png,META-INF/teavm.properties=$MODULE_DIR$/src/main/resources/META-INF/teavm.properties,META-INF/services/org.teavm.vm.spi.TeaVMPlugin=$MODULE_DIR$/src/main/resources/META-INF/services/org.teavm.vm.spi.TeaVMPlugin" />
|
||||
</additionalProperties>
|
||||
<additionalJARContents />
|
||||
</configuration>
|
||||
|
|
|
@ -18,10 +18,6 @@ package org.teavm.debugging.information;
|
|||
import org.teavm.codegen.LocationProvider;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface DebugInformationEmitter {
|
||||
void setLocationProvider(LocationProvider locationProvider);
|
||||
|
||||
|
|
|
@ -18,10 +18,6 @@ package org.teavm.vm;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface BuildTarget {
|
||||
OutputStream createResource(String fileName) throws IOException;
|
||||
}
|
||||
|
|
|
@ -19,58 +19,32 @@ import java.io.File;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.teavm.cache.NoCache;
|
||||
import org.teavm.codegen.AliasProvider;
|
||||
import org.teavm.codegen.DefaultAliasProvider;
|
||||
import org.teavm.codegen.DefaultNamingStrategy;
|
||||
import org.teavm.codegen.MinifyingAliasProvider;
|
||||
import org.teavm.codegen.SourceWriter;
|
||||
import org.teavm.codegen.SourceWriterBuilder;
|
||||
import org.teavm.common.ServiceRepository;
|
||||
import org.teavm.debugging.information.DebugInformationEmitter;
|
||||
import org.teavm.debugging.information.SourceLocation;
|
||||
import org.teavm.dependency.BootstrapMethodSubstitutor;
|
||||
import org.teavm.dependency.DependencyChecker;
|
||||
import org.teavm.dependency.DependencyInfo;
|
||||
import org.teavm.dependency.DependencyListener;
|
||||
import org.teavm.dependency.Linker;
|
||||
import org.teavm.dependency.MethodDependency;
|
||||
import org.teavm.diagnostics.AccumulationDiagnostics;
|
||||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.diagnostics.ProblemProvider;
|
||||
import org.teavm.javascript.Decompiler;
|
||||
import org.teavm.javascript.EmptyRegularMethodNodeCache;
|
||||
import org.teavm.javascript.MethodNodeCache;
|
||||
import org.teavm.javascript.Renderer;
|
||||
import org.teavm.javascript.RenderingException;
|
||||
import org.teavm.javascript.ast.ClassNode;
|
||||
import org.teavm.javascript.spi.GeneratedBy;
|
||||
import org.teavm.javascript.spi.Generator;
|
||||
import org.teavm.javascript.spi.InjectedBy;
|
||||
import org.teavm.javascript.spi.Injector;
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassHolder;
|
||||
import org.teavm.model.ClassHolderSource;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
import org.teavm.model.ElementHolder;
|
||||
import org.teavm.model.ElementModifier;
|
||||
import org.teavm.model.InstructionLocation;
|
||||
import org.teavm.model.ListableClassHolderSource;
|
||||
import org.teavm.model.ListableClassReaderSource;
|
||||
import org.teavm.model.MethodHolder;
|
||||
|
@ -78,15 +52,6 @@ import org.teavm.model.MethodReference;
|
|||
import org.teavm.model.MutableClassHolderSource;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.ProgramCache;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.model.Variable;
|
||||
import org.teavm.model.instructions.ConstructInstruction;
|
||||
import org.teavm.model.instructions.InvocationType;
|
||||
import org.teavm.model.instructions.InvokeInstruction;
|
||||
import org.teavm.model.instructions.RaiseInstruction;
|
||||
import org.teavm.model.instructions.StringConstantInstruction;
|
||||
import org.teavm.model.util.AsyncMethodFinder;
|
||||
import org.teavm.model.util.ListingBuilder;
|
||||
import org.teavm.model.util.MissingItemsProcessor;
|
||||
import org.teavm.model.util.ModelUtils;
|
||||
import org.teavm.model.util.ProgramUtils;
|
||||
|
@ -103,8 +68,8 @@ import org.teavm.optimization.MethodOptimization;
|
|||
import org.teavm.optimization.RedundantJumpElimination;
|
||||
import org.teavm.optimization.UnreachableBasicBlockElimination;
|
||||
import org.teavm.optimization.UnusedVariableElimination;
|
||||
import org.teavm.vm.spi.RendererListener;
|
||||
import org.teavm.vm.spi.TeaVMHost;
|
||||
import org.teavm.vm.spi.TeaVMHostExtension;
|
||||
import org.teavm.vm.spi.TeaVMPlugin;
|
||||
|
||||
/**
|
||||
|
@ -141,29 +106,24 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
private final DependencyChecker dependencyChecker;
|
||||
private final AccumulationDiagnostics diagnostics = new AccumulationDiagnostics();
|
||||
private final ClassLoader classLoader;
|
||||
private boolean minifying = true;
|
||||
private boolean bytecodeLogging;
|
||||
private final OutputStream logStream = System.out;
|
||||
private final Map<String, TeaVMEntryPoint> entryPoints = new HashMap<>();
|
||||
private final Map<String, TeaVMEntryPoint> readonlyEntryPoints = Collections.unmodifiableMap(entryPoints);
|
||||
private final Map<String, String> exportedClasses = new HashMap<>();
|
||||
private final Map<MethodReference, Generator> methodGenerators = new HashMap<>();
|
||||
private final Map<MethodReference, Injector> methodInjectors = new HashMap<>();
|
||||
private final List<RendererListener> rendererListeners = new ArrayList<>();
|
||||
private final Map<String, String> readonlyExportedClasses = Collections.unmodifiableMap(exportedClasses);
|
||||
private final Map<Class<?>, Object> services = new HashMap<>();
|
||||
private final Properties properties = new Properties();
|
||||
private DebugInformationEmitter debugEmitter;
|
||||
private ProgramCache programCache;
|
||||
private MethodNodeCache astCache = new EmptyRegularMethodNodeCache();
|
||||
private boolean incremental;
|
||||
private TeaVMProgressListener progressListener;
|
||||
private boolean cancelled;
|
||||
private ListableClassHolderSource writtenClasses;
|
||||
private final Set<MethodReference> asyncMethods = new HashSet<>();
|
||||
private final Set<MethodReference> asyncFamilyMethods = new HashSet<>();
|
||||
private TeaVMTarget target;
|
||||
private Map<Class<?>, TeaVMHostExtension> extensions = new HashMap<>();
|
||||
|
||||
TeaVM(ClassReaderSource classSource, ClassLoader classLoader) {
|
||||
this.classSource = classSource;
|
||||
this.classLoader = classLoader;
|
||||
TeaVM(TeaVMBuilder builder) {
|
||||
target = builder.target;
|
||||
classSource = builder.classSource;
|
||||
classLoader = builder.classLoader;
|
||||
dependencyChecker = new DependencyChecker(this.classSource, classLoader, this, diagnostics);
|
||||
progressListener = new TeaVMProgressListener() {
|
||||
@Override public TeaVMProgressFeedback progressReached(int progress) {
|
||||
|
@ -173,6 +133,12 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
return TeaVMProgressFeedback.CONTINUE;
|
||||
}
|
||||
};
|
||||
|
||||
for (TeaVMHostExtension extension : target.getHostExtensions()) {
|
||||
for (Class<?> extensionType : getExtensionTypes(extension)) {
|
||||
extensions.put(extensionType, extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -185,59 +151,16 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
dependencyChecker.addClassTransformer(transformer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(MethodReference methodRef, Generator generator) {
|
||||
methodGenerators.put(methodRef, generator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(MethodReference methodRef, Injector injector) {
|
||||
methodInjectors.put(methodRef, injector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(MethodReference methodRef, BootstrapMethodSubstitutor substitutor) {
|
||||
dependencyChecker.addBootstrapMethodSubstitutor(methodRef, substitutor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(RendererListener listener) {
|
||||
rendererListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports whether this TeaVM instance uses obfuscation when generating the JavaScript code.
|
||||
*
|
||||
* @see #setMinifying(boolean)
|
||||
* @return whether TeaVM produces obfuscated code.
|
||||
*/
|
||||
public boolean isMinifying() {
|
||||
return minifying;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether this TeaVM instance uses obfuscation when generating the JavaScript code.
|
||||
*
|
||||
* @see #isMinifying()
|
||||
* @param minifying whether TeaVM should obfuscate code.
|
||||
*/
|
||||
public void setMinifying(boolean minifying) {
|
||||
this.minifying = minifying;
|
||||
}
|
||||
|
||||
public boolean isBytecodeLogging() {
|
||||
return bytecodeLogging;
|
||||
}
|
||||
|
||||
public void setBytecodeLogging(boolean bytecodeLogging) {
|
||||
this.bytecodeLogging = bytecodeLogging;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies configuration properties for TeaVM and its plugins. You should call this method before
|
||||
* installing any plugins or interceptors.
|
||||
|
@ -257,14 +180,6 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
return new Properties(properties);
|
||||
}
|
||||
|
||||
public MethodNodeCache getAstCache() {
|
||||
return astCache;
|
||||
}
|
||||
|
||||
public void setAstCache(MethodNodeCache methodAstCache) {
|
||||
this.astCache = methodAstCache;
|
||||
}
|
||||
|
||||
public ProgramCache getProgramCache() {
|
||||
return programCache;
|
||||
}
|
||||
|
@ -391,14 +306,6 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
return writtenClasses;
|
||||
}
|
||||
|
||||
public DebugInformationEmitter getDebugEmitter() {
|
||||
return debugEmitter;
|
||||
}
|
||||
|
||||
public void setDebugEmitter(DebugInformationEmitter debugEmitter) {
|
||||
this.debugEmitter = debugEmitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Does actual build. Call this method after TeaVM is fully configured and all entry points
|
||||
* are specified. This method may fail if there are items (classes, methods and fields)
|
||||
|
@ -406,52 +313,23 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
* actual generation happens and no exceptions thrown, but you can further call
|
||||
* {@link #getProblemProvider()} to learn the build state.</p>
|
||||
*
|
||||
* @param writer where to generate JavaScript. Should not be null.
|
||||
* @param target where to generate additional resources. Can be null, but if there are
|
||||
* @param output where to generate JavaScript. Should not be null.
|
||||
* @param buildTarget where to generate additional resources. Can be null, but if there are
|
||||
* plugins or inteceptors that generate additional resources, the build process will fail.
|
||||
*
|
||||
* @throws RenderingException when something went wrong during rendering phase.
|
||||
*/
|
||||
public void build(Appendable writer, BuildTarget target) throws RenderingException {
|
||||
public void build(OutputStream output, BuildTarget buildTarget) throws RenderingException {
|
||||
target.setController(targetController);
|
||||
|
||||
// Check dependencies
|
||||
reportPhase(TeaVMPhase.DEPENDENCY_CHECKING, 1);
|
||||
if (wasCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AliasProvider aliasProvider = minifying ? new MinifyingAliasProvider() : new DefaultAliasProvider();
|
||||
dependencyChecker.setInterruptor(() -> progressListener.progressReached(0) == TeaVMProgressFeedback.CONTINUE);
|
||||
dependencyChecker.linkMethod(new MethodReference(Class.class.getName(), "getClass",
|
||||
ValueType.object("org.teavm.platform.PlatformClass"), ValueType.parse(Class.class)), null).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(String.class, "<init>", char[].class, void.class),
|
||||
null).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(String.class, "getChars", int.class, int.class, char[].class,
|
||||
int.class, void.class), null).use();
|
||||
MethodDependency internDep = dependencyChecker.linkMethod(new MethodReference(String.class, "intern",
|
||||
String.class), null);
|
||||
internDep.getVariable(0).propagate(dependencyChecker.getType("java.lang.String"));
|
||||
internDep.use();
|
||||
dependencyChecker.linkMethod(new MethodReference(String.class, "length", int.class), null).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(Object.class, "clone", Object.class), null).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(Thread.class, "currentThread", Thread.class), null).use();
|
||||
dependencyChecker.linkMethod(new MethodReference(Thread.class, "getMainThread", Thread.class), null).use();
|
||||
dependencyChecker.linkMethod(
|
||||
new MethodReference(Thread.class, "setCurrentThread", Thread.class, void.class), null).use();
|
||||
MethodDependency exceptionCons = dependencyChecker.linkMethod(new MethodReference(
|
||||
NoClassDefFoundError.class, "<init>", String.class, void.class), null);
|
||||
exceptionCons.use();
|
||||
exceptionCons.getVariable(0).propagate(dependencyChecker.getType(NoClassDefFoundError.class.getName()));
|
||||
exceptionCons.getVariable(1).propagate(dependencyChecker.getType("java.lang.String"));
|
||||
exceptionCons = dependencyChecker.linkMethod(new MethodReference(NoSuchFieldError.class, "<init>",
|
||||
String.class, void.class), null);
|
||||
exceptionCons.use();
|
||||
exceptionCons.getVariable(0).propagate(dependencyChecker.getType(NoSuchFieldError.class.getName()));
|
||||
exceptionCons.getVariable(1).propagate(dependencyChecker.getType("java.lang.String"));
|
||||
exceptionCons = dependencyChecker.linkMethod(new MethodReference(NoSuchMethodError.class, "<init>",
|
||||
String.class, void.class), null);
|
||||
exceptionCons.use();
|
||||
exceptionCons.getVariable(0).propagate(dependencyChecker.getType(NoSuchMethodError.class.getName()));
|
||||
exceptionCons.getVariable(1).propagate(dependencyChecker.getType("java.lang.String"));
|
||||
target.contributeDependencies(dependencyChecker);
|
||||
dependencyChecker.processDependencies();
|
||||
if (wasCancelled() || !diagnostics.getSevereProblems().isEmpty()) {
|
||||
return;
|
||||
|
@ -469,73 +347,27 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
}
|
||||
|
||||
// Optimize and allocate registers
|
||||
reportPhase(TeaVMPhase.OPTIMIZATION, 1);
|
||||
|
||||
if (!incremental) {
|
||||
devirtualize(classSet, dependencyChecker);
|
||||
if (wasCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
inline(classSet);
|
||||
if (wasCancelled()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
List<ClassNode> clsNodes = modelToAst(classSet);
|
||||
optimize(classSet);
|
||||
if (wasCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Render
|
||||
reportPhase(TeaVMPhase.RENDERING, classSet.getClassNames().size());
|
||||
if (wasCancelled()) {
|
||||
return;
|
||||
}
|
||||
DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, dependencyChecker.getClassSource());
|
||||
SourceWriterBuilder builder = new SourceWriterBuilder(naming);
|
||||
builder.setMinified(minifying);
|
||||
SourceWriter sourceWriter = builder.build(writer);
|
||||
Renderer renderer = new Renderer(sourceWriter, classSet, classLoader, this, asyncMethods, asyncFamilyMethods,
|
||||
diagnostics);
|
||||
renderer.setProperties(properties);
|
||||
renderer.setMinifying(minifying);
|
||||
if (debugEmitter != null) {
|
||||
int classIndex = 0;
|
||||
for (String className : classSet.getClassNames()) {
|
||||
ClassHolder cls = classSet.get(className);
|
||||
for (MethodHolder method : cls.getMethods()) {
|
||||
if (method.getProgram() != null) {
|
||||
emitCFG(debugEmitter, method.getProgram());
|
||||
}
|
||||
}
|
||||
reportProgress(++classIndex);
|
||||
if (wasCancelled()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
renderer.setDebugEmitter(debugEmitter);
|
||||
}
|
||||
renderer.getDebugEmitter().setLocationProvider(sourceWriter);
|
||||
for (Map.Entry<MethodReference, Injector> entry : methodInjectors.entrySet()) {
|
||||
renderer.addInjector(entry.getKey(), entry.getValue());
|
||||
}
|
||||
try {
|
||||
for (RendererListener listener : rendererListeners) {
|
||||
listener.begin(renderer, target);
|
||||
}
|
||||
sourceWriter.append("\"use strict\";").newLine();
|
||||
renderer.renderRuntime();
|
||||
renderer.render(clsNodes);
|
||||
renderer.renderStringPool();
|
||||
renderer.renderStringConstants();
|
||||
for (Map.Entry<String, TeaVMEntryPoint> entry : entryPoints.entrySet()) {
|
||||
sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws();
|
||||
MethodReference ref = entry.getValue().reference;
|
||||
sourceWriter.append(naming.getFullNameFor(ref));
|
||||
sourceWriter.append(";").newLine();
|
||||
}
|
||||
for (Map.Entry<String, String> entry : exportedClasses.entrySet()) {
|
||||
sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws()
|
||||
.appendClass(entry.getValue()).append(";").newLine();
|
||||
}
|
||||
for (RendererListener listener : rendererListeners) {
|
||||
listener.complete();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RenderingException("IO Error occured", e);
|
||||
}
|
||||
target.emit(classSet, output, buildTarget);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
|
@ -568,38 +400,11 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
}
|
||||
}
|
||||
|
||||
private void reportProgress(int progress) {
|
||||
if (progressListener.progressReached(progress) == TeaVMProgressFeedback.CANCEL) {
|
||||
cancelled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void emitCFG(DebugInformationEmitter emitter, Program program) {
|
||||
Map<InstructionLocation, InstructionLocation[]> cfg = ProgramUtils.getLocationCFG(program);
|
||||
for (Map.Entry<InstructionLocation, InstructionLocation[]> entry : cfg.entrySet()) {
|
||||
SourceLocation location = map(entry.getKey());
|
||||
SourceLocation[] successors = new SourceLocation[entry.getValue().length];
|
||||
for (int i = 0; i < entry.getValue().length; ++i) {
|
||||
successors[i] = map(entry.getValue()[i]);
|
||||
}
|
||||
emitter.addSuccessors(location, successors);
|
||||
}
|
||||
}
|
||||
|
||||
private static SourceLocation map(InstructionLocation location) {
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
return new SourceLocation(location.getFileName(), location.getLine());
|
||||
}
|
||||
|
||||
private void devirtualize(ListableClassHolderSource classes, DependencyInfo dependency) {
|
||||
reportPhase(TeaVMPhase.DEVIRTUALIZATION, classes.getClassNames().size());
|
||||
if (wasCancelled()) {
|
||||
return;
|
||||
}
|
||||
Devirtualization devirtualization = new Devirtualization(dependency, classes);
|
||||
int index = 0;
|
||||
for (String className : classes.getClassNames()) {
|
||||
ClassHolder cls = classes.get(className);
|
||||
for (final MethodHolder method : cls.getMethods()) {
|
||||
|
@ -607,12 +412,13 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
devirtualization.apply(method);
|
||||
}
|
||||
}
|
||||
reportProgress(++index);
|
||||
if (wasCancelled()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void inline(ListableClassHolderSource classes) {
|
||||
Inlining inlining = new Inlining();
|
||||
for (String className : classes.getClassNames()) {
|
||||
ClassHolder cls = classes.get(className);
|
||||
|
@ -621,90 +427,22 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
inlining.apply(method.getProgram(), classes);
|
||||
}
|
||||
}
|
||||
reportProgress(++index);
|
||||
if (wasCancelled()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<ClassNode> modelToAst(ListableClassHolderSource classes) {
|
||||
AsyncMethodFinder asyncFinder = new AsyncMethodFinder(dependencyChecker.getCallGraph(), diagnostics);
|
||||
asyncFinder.find(classes);
|
||||
asyncMethods.addAll(asyncFinder.getAsyncMethods());
|
||||
asyncFamilyMethods.addAll(asyncFinder.getAsyncFamilyMethods());
|
||||
|
||||
progressListener.phaseStarted(TeaVMPhase.DECOMPILATION, classes.getClassNames().size());
|
||||
Decompiler decompiler = new Decompiler(classes, classLoader, asyncMethods, asyncFamilyMethods);
|
||||
decompiler.setRegularMethodCache(incremental ? astCache : null);
|
||||
|
||||
for (Map.Entry<MethodReference, Generator> entry : methodGenerators.entrySet()) {
|
||||
decompiler.addGenerator(entry.getKey(), entry.getValue());
|
||||
}
|
||||
for (MethodReference injectedMethod : methodInjectors.keySet()) {
|
||||
decompiler.addMethodToPass(injectedMethod);
|
||||
}
|
||||
List<String> classOrder = decompiler.getClassOrdering(classes.getClassNames());
|
||||
List<ClassNode> classNodes = new ArrayList<>();
|
||||
int index = 0;
|
||||
try (PrintWriter bytecodeLogger = bytecodeLogging
|
||||
? new PrintWriter(new OutputStreamWriter(logStream, "UTF-8")) : null) {
|
||||
for (String className : classOrder) {
|
||||
ClassHolder cls = classes.get(className);
|
||||
private void optimize(ListableClassHolderSource classSource) {
|
||||
for (String className : classSource.getClassNames()) {
|
||||
ClassHolder cls = classSource.get(className);
|
||||
for (MethodHolder method : cls.getMethods()) {
|
||||
processMethod(method);
|
||||
preprocessNativeMethod(method);
|
||||
if (bytecodeLogging) {
|
||||
logMethodBytecode(bytecodeLogger, method);
|
||||
}
|
||||
}
|
||||
classNodes.add(decompiler.decompile(cls));
|
||||
progressListener.progressReached(++index);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError("UTF-8 is expected to be supported");
|
||||
}
|
||||
return classNodes;
|
||||
}
|
||||
|
||||
private void preprocessNativeMethod(MethodHolder method) {
|
||||
if (!method.getModifiers().contains(ElementModifier.NATIVE)
|
||||
|| methodGenerators.get(method.getReference()) != null
|
||||
|| methodInjectors.get(method.getReference()) != null
|
||||
|| method.getAnnotations().get(GeneratedBy.class.getName()) != null
|
||||
|| method.getAnnotations().get(InjectedBy.class.getName()) != null) {
|
||||
if (wasCancelled()) {
|
||||
return;
|
||||
}
|
||||
method.getModifiers().remove(ElementModifier.NATIVE);
|
||||
|
||||
Program program = new Program();
|
||||
method.setProgram(program);
|
||||
BasicBlock block = program.createBasicBlock();
|
||||
Variable exceptionVar = program.createVariable();
|
||||
ConstructInstruction newExceptionInsn = new ConstructInstruction();
|
||||
newExceptionInsn.setType(NoSuchMethodError.class.getName());
|
||||
newExceptionInsn.setReceiver(exceptionVar);
|
||||
block.getInstructions().add(newExceptionInsn);
|
||||
|
||||
Variable constVar = program.createVariable();
|
||||
StringConstantInstruction constInsn = new StringConstantInstruction();
|
||||
constInsn.setConstant("Native method implementation not found: " + method.getReference());
|
||||
constInsn.setReceiver(constVar);
|
||||
block.getInstructions().add(constInsn);
|
||||
|
||||
InvokeInstruction initExceptionInsn = new InvokeInstruction();
|
||||
initExceptionInsn.setInstance(exceptionVar);
|
||||
initExceptionInsn.setMethod(new MethodReference(NoSuchMethodError.class, "<init>", String.class, void.class));
|
||||
initExceptionInsn.setType(InvocationType.SPECIAL);
|
||||
initExceptionInsn.getArguments().add(constVar);
|
||||
block.getInstructions().add(initExceptionInsn);
|
||||
|
||||
RaiseInstruction raiseInsn = new RaiseInstruction();
|
||||
raiseInsn.setException(exceptionVar);
|
||||
block.getInstructions().add(raiseInsn);
|
||||
|
||||
diagnostics.error(new CallLocation(method.getReference()), "Native method {{m0}} has no implementation",
|
||||
method.getReference());
|
||||
}
|
||||
}
|
||||
|
||||
private void processMethod(MethodHolder method) {
|
||||
|
@ -725,9 +463,12 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
changed |= optimization.optimize(method, optimizedProgram);
|
||||
}
|
||||
} while (changed);
|
||||
|
||||
if (target.requiresRegisterAllocation()) {
|
||||
RegisterAllocator allocator = new RegisterAllocator();
|
||||
allocator.allocateRegisters(method, optimizedProgram);
|
||||
}
|
||||
}
|
||||
if (incremental && programCache != null) {
|
||||
programCache.store(method.getReference(), optimizedProgram);
|
||||
}
|
||||
|
@ -749,102 +490,9 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
new UnreachableBasicBlockElimination());
|
||||
}
|
||||
|
||||
private void logMethodBytecode(PrintWriter writer, MethodHolder method) {
|
||||
writer.print(" ");
|
||||
printModifiers(writer, method);
|
||||
writer.print(method.getName() + "(");
|
||||
ValueType[] parameterTypes = method.getParameterTypes();
|
||||
for (int i = 0; i < parameterTypes.length; ++i) {
|
||||
if (i > 0) {
|
||||
writer.print(", ");
|
||||
}
|
||||
printType(writer, parameterTypes[i]);
|
||||
}
|
||||
writer.println(")");
|
||||
Program program = method.getProgram();
|
||||
if (program != null && program.basicBlockCount() > 0) {
|
||||
ListingBuilder builder = new ListingBuilder();
|
||||
writer.print(builder.buildListing(program, " "));
|
||||
writer.print(" Register allocation:");
|
||||
for (int i = 0; i < program.variableCount(); ++i) {
|
||||
writer.print(i + ":" + program.variableAt(i).getRegister() + " ");
|
||||
}
|
||||
writer.println();
|
||||
writer.println();
|
||||
writer.flush();
|
||||
} else {
|
||||
writer.println();
|
||||
}
|
||||
}
|
||||
|
||||
private void printType(PrintWriter writer, ValueType type) {
|
||||
if (type instanceof ValueType.Object) {
|
||||
writer.print(((ValueType.Object) type).getClassName());
|
||||
} else if (type instanceof ValueType.Array) {
|
||||
printType(writer, ((ValueType.Array) type).getItemType());
|
||||
writer.print("[]");
|
||||
} else if (type instanceof ValueType.Primitive) {
|
||||
switch (((ValueType.Primitive) type).getKind()) {
|
||||
case BOOLEAN:
|
||||
writer.print("boolean");
|
||||
break;
|
||||
case SHORT:
|
||||
writer.print("short");
|
||||
break;
|
||||
case BYTE:
|
||||
writer.print("byte");
|
||||
break;
|
||||
case CHARACTER:
|
||||
writer.print("char");
|
||||
break;
|
||||
case DOUBLE:
|
||||
writer.print("double");
|
||||
break;
|
||||
case FLOAT:
|
||||
writer.print("float");
|
||||
break;
|
||||
case INTEGER:
|
||||
writer.print("int");
|
||||
break;
|
||||
case LONG:
|
||||
writer.print("long");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void printModifiers(PrintWriter writer, ElementHolder element) {
|
||||
switch (element.getLevel()) {
|
||||
case PRIVATE:
|
||||
writer.print("private ");
|
||||
break;
|
||||
case PUBLIC:
|
||||
writer.print("public ");
|
||||
break;
|
||||
case PROTECTED:
|
||||
writer.print("protected ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Set<ElementModifier> modifiers = element.getModifiers();
|
||||
if (modifiers.contains(ElementModifier.ABSTRACT)) {
|
||||
writer.print("abstract ");
|
||||
}
|
||||
if (modifiers.contains(ElementModifier.FINAL)) {
|
||||
writer.print("final ");
|
||||
}
|
||||
if (modifiers.contains(ElementModifier.STATIC)) {
|
||||
writer.print("static ");
|
||||
}
|
||||
if (modifiers.contains(ElementModifier.NATIVE)) {
|
||||
writer.print("native ");
|
||||
}
|
||||
}
|
||||
|
||||
public void build(File dir, String fileName) throws RenderingException {
|
||||
try (Writer writer = new OutputStreamWriter(new FileOutputStream(new File(dir, fileName)), "UTF-8")) {
|
||||
build(writer, new DirectoryBuildTarget(dir));
|
||||
try (OutputStream output = new FileOutputStream(new File(dir, fileName))) {
|
||||
build(output, new DirectoryBuildTarget(dir));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("Platform does not support UTF-8", e);
|
||||
} catch (IOException e) {
|
||||
|
@ -877,4 +525,69 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
public <T> void registerService(Class<T> type, T instance) {
|
||||
services.put(type, instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends TeaVMHostExtension> T getExtension(Class<T> extensionType) {
|
||||
Object extension = extensions.get(extensionType);
|
||||
return extension != null ? extensionType.cast(extension) : null;
|
||||
}
|
||||
|
||||
private Collection<Class<? extends TeaVMHostExtension>> getExtensionTypes(TeaVMHostExtension extension) {
|
||||
return Arrays.stream(extension.getClass().getInterfaces())
|
||||
.filter(cls -> cls.isInterface() && TeaVMHostExtension.class.isAssignableFrom(cls))
|
||||
.<Class<? extends TeaVMHostExtension>>map(cls -> cls.asSubclass(TeaVMHostExtension.class))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private TeaVMTargetController targetController = new TeaVMTargetController() {
|
||||
@Override
|
||||
public boolean wasCancelled() {
|
||||
return TeaVM.this.wasCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassReaderSource getUnprocessedClassSource() {
|
||||
return dependencyChecker.getClassSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DependencyInfo getDependencyInfo() {
|
||||
return dependencyChecker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Diagnostics getDiagnostics() {
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceRepository getServices() {
|
||||
return TeaVM.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncremental() {
|
||||
return incremental;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, TeaVMEntryPoint> getEntryPoints() {
|
||||
return readonlyEntryPoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getExportedClasses() {
|
||||
return readonlyExportedClasses;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,15 +18,13 @@ package org.teavm.vm;
|
|||
import org.teavm.model.ClassHolderSource;
|
||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TeaVMBuilder {
|
||||
TeaVMTarget target;
|
||||
ClassHolderSource classSource;
|
||||
ClassLoader classLoader;
|
||||
|
||||
public TeaVMBuilder() {
|
||||
public TeaVMBuilder(TeaVMTarget target) {
|
||||
this.target = target;
|
||||
classLoader = TeaVMBuilder.class.getClassLoader();
|
||||
classSource = new ClasspathClassHolderSource(classLoader);
|
||||
}
|
||||
|
@ -50,6 +48,6 @@ public class TeaVMBuilder {
|
|||
}
|
||||
|
||||
public TeaVM build() {
|
||||
return new TeaVM(classSource, classLoader);
|
||||
return new TeaVM(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,10 @@ public class TeaVMEntryPoint {
|
|||
method.use();
|
||||
}
|
||||
|
||||
public MethodReference getReference() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
String getPublicName() {
|
||||
return publicName;
|
||||
}
|
||||
|
|
|
@ -15,14 +15,10 @@
|
|||
*/
|
||||
package org.teavm.vm;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public enum TeaVMPhase {
|
||||
DEPENDENCY_CHECKING,
|
||||
LINKING,
|
||||
DEVIRTUALIZATION,
|
||||
OPTIMIZATION,
|
||||
DECOMPILATION,
|
||||
RENDERING
|
||||
}
|
||||
|
|
34
core/src/main/java/org/teavm/vm/TeaVMTarget.java
Normal file
34
core/src/main/java/org/teavm/vm/TeaVMTarget.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2016 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;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import org.teavm.dependency.DependencyChecker;
|
||||
import org.teavm.model.ListableClassHolderSource;
|
||||
import org.teavm.vm.spi.TeaVMHostExtension;
|
||||
|
||||
public interface TeaVMTarget {
|
||||
void setController(TeaVMTargetController controller);
|
||||
|
||||
List<TeaVMHostExtension> getHostExtensions();
|
||||
|
||||
boolean requiresRegisterAllocation();
|
||||
|
||||
void contributeDependencies(DependencyChecker dependencyChecker);
|
||||
|
||||
void emit(ListableClassHolderSource classes, OutputStream output, BuildTarget buildTarget);
|
||||
}
|
45
core/src/main/java/org/teavm/vm/TeaVMTargetController.java
Normal file
45
core/src/main/java/org/teavm/vm/TeaVMTargetController.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2016 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;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import org.teavm.common.ServiceRepository;
|
||||
import org.teavm.dependency.DependencyInfo;
|
||||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
|
||||
public interface TeaVMTargetController {
|
||||
boolean wasCancelled();
|
||||
|
||||
ClassLoader getClassLoader();
|
||||
|
||||
ClassReaderSource getUnprocessedClassSource();
|
||||
|
||||
DependencyInfo getDependencyInfo();
|
||||
|
||||
Diagnostics getDiagnostics();
|
||||
|
||||
Properties getProperties();
|
||||
|
||||
ServiceRepository getServices();
|
||||
|
||||
boolean isIncremental();
|
||||
|
||||
Map<String, TeaVMEntryPoint> getEntryPoints();
|
||||
|
||||
Map<String, String> getExportedClasses();
|
||||
}
|
|
@ -18,8 +18,6 @@ package org.teavm.vm.spi;
|
|||
import java.util.Properties;
|
||||
import org.teavm.dependency.BootstrapMethodSubstitutor;
|
||||
import org.teavm.dependency.DependencyListener;
|
||||
import org.teavm.javascript.spi.Generator;
|
||||
import org.teavm.javascript.spi.Injector;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.vm.TeaVM;
|
||||
|
@ -36,13 +34,9 @@ public interface TeaVMHost {
|
|||
|
||||
void add(ClassHolderTransformer classTransformer);
|
||||
|
||||
void add(MethodReference methodRef, Generator generator);
|
||||
|
||||
void add(MethodReference methodRef, Injector injector);
|
||||
|
||||
void add(MethodReference methodRef, BootstrapMethodSubstitutor substitutor);
|
||||
|
||||
void add(RendererListener listener);
|
||||
<T extends TeaVMHostExtension> T getExtension(Class<T> extensionType);
|
||||
|
||||
<T> void registerService(Class<T> type, T instance);
|
||||
|
||||
|
|
19
core/src/main/java/org/teavm/vm/spi/TeaVMHostExtension.java
Normal file
19
core/src/main/java/org/teavm/vm/spi/TeaVMHostExtension.java
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright 2016 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;
|
||||
|
||||
public interface TeaVMHostExtension {
|
||||
}
|
|
@ -15,10 +15,6 @@
|
|||
*/
|
||||
package org.teavm.vm.spi;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface TeaVMPlugin {
|
||||
void install(TeaVMHost host);
|
||||
}
|
||||
|
|
|
@ -15,19 +15,20 @@
|
|||
*/
|
||||
package org.teavm.html4j;
|
||||
|
||||
import org.teavm.javascript.target.TeaVMJavaScriptHost;
|
||||
import org.teavm.vm.spi.TeaVMHost;
|
||||
import org.teavm.vm.spi.TeaVMPlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class HTML4JPlugin implements TeaVMPlugin {
|
||||
@Override
|
||||
public void install(TeaVMHost host) {
|
||||
if (host.getExtension(TeaVMJavaScriptHost.class) == null) {
|
||||
return;
|
||||
}
|
||||
host.add(new JavaScriptBodyDependency());
|
||||
host.add(new JavaScriptBodyTransformer());
|
||||
host.add(new JCLHacks());
|
||||
host.add(new JavaScriptResourceInterceptor());
|
||||
|
||||
host.getExtension(TeaVMJavaScriptHost.class).add(new JavaScriptResourceInterceptor());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,22 +15,23 @@
|
|||
*/
|
||||
package org.teavm.jso.impl;
|
||||
|
||||
import org.teavm.javascript.target.TeaVMJavaScriptHost;
|
||||
import org.teavm.vm.spi.TeaVMHost;
|
||||
import org.teavm.vm.spi.TeaVMPlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class JSOPlugin implements TeaVMPlugin {
|
||||
@Override
|
||||
public void install(TeaVMHost host) {
|
||||
if (host.getExtension(TeaVMJavaScriptHost.class) == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSBodyRepository repository = new JSBodyRepository();
|
||||
host.registerService(JSBodyRepository.class, repository);
|
||||
host.add(new JSObjectClassTransformer(repository));
|
||||
JSDependencyListener dependencyListener = new JSDependencyListener(repository);
|
||||
JSAliasRenderer aliasRenderer = new JSAliasRenderer(dependencyListener);
|
||||
host.add(dependencyListener);
|
||||
host.add(aliasRenderer);
|
||||
host.getExtension(TeaVMJavaScriptHost.class).add(aliasRenderer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,6 @@ package org.teavm.platform.plugin;
|
|||
import org.teavm.vm.spi.TeaVMHost;
|
||||
import org.teavm.vm.spi.TeaVMPlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class PlatformPlugin implements TeaVMPlugin {
|
||||
@Override
|
||||
public void install(TeaVMHost host) {
|
||||
|
|
|
@ -16,18 +16,15 @@
|
|||
package org.teavm.platform.plugin;
|
||||
|
||||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.javascript.target.TeaVMJavaScriptHost;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.vm.spi.TeaVMHost;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
class ResourceAccessorTransformer implements ClassHolderTransformer {
|
||||
private TeaVMHost vm;
|
||||
private TeaVMJavaScriptHost vm;
|
||||
|
||||
public ResourceAccessorTransformer(TeaVMHost vm) {
|
||||
this.vm = vm;
|
||||
this.vm = vm.getExtension(TeaVMJavaScriptHost.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,7 +17,9 @@ package org.teavm.dependency;
|
|||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||
import org.junit.Test;
|
||||
import org.teavm.javascript.target.JavaScriptTarget;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.tooling.TeaVMProblemRenderer;
|
||||
|
@ -73,10 +75,10 @@ public class ClassValueTest {
|
|||
}
|
||||
|
||||
private DependencyInfo runTest(String methodName) {
|
||||
TeaVM vm = new TeaVMBuilder().build();
|
||||
TeaVM vm = new TeaVMBuilder(new JavaScriptTarget()).build();
|
||||
vm.installPlugins();
|
||||
vm.entryPoint(new MethodReference(getClass().getName(), methodName, ValueType.VOID));
|
||||
vm.build(new StringBuilder(), null);
|
||||
vm.build(new ByteArrayOutputStream(), null);
|
||||
if (!vm.getProblemProvider().getSevereProblems().isEmpty()) {
|
||||
fail("Code compiled with errors:\n" + describeProblems(vm));
|
||||
}
|
||||
|
|
|
@ -15,15 +15,15 @@
|
|||
*/
|
||||
package org.teavm.tests;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.teavm.diagnostics.Problem;
|
||||
import org.teavm.javascript.target.JavaScriptTarget;
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.junit.SkipJVM;
|
||||
import org.teavm.junit.TeaVMTestRunner;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.vm.TeaVM;
|
||||
|
@ -96,10 +96,10 @@ public class JSOTest {
|
|||
private static native Object jsBodyWithWrongReturningType(String value);
|
||||
|
||||
private List<Problem> build(String methodName) {
|
||||
TeaVM vm = new TeaVMBuilder().build();
|
||||
TeaVM vm = new TeaVMBuilder(new JavaScriptTarget()).build();
|
||||
vm.installPlugins();
|
||||
vm.entryPoint("org/teavm/metaprogramming/test", new MethodReference(JSOTest.class, methodName, void.class));
|
||||
vm.build(new StringBuilder(), null);
|
||||
vm.build(new ByteArrayOutputStream(), null);
|
||||
return vm.getProblemProvider().getSevereProblems();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,6 @@ import org.teavm.vm.TeaVMPhase;
|
|||
import org.teavm.vm.TeaVMProgressFeedback;
|
||||
import org.teavm.vm.TeaVMProgressListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public final class TeaVMRunner {
|
||||
private static long startTime;
|
||||
private static long phaseStartTime;
|
||||
|
@ -69,10 +65,6 @@ public final class TeaVMRunner {
|
|||
.withDescription("causes TeaVM to include default main page")
|
||||
.withLongOpt("mainpage")
|
||||
.create());
|
||||
options.addOption(OptionBuilder
|
||||
.withDescription("causes TeaVM to log bytecode")
|
||||
.withLongOpt("logbytecode")
|
||||
.create());
|
||||
options.addOption(OptionBuilder
|
||||
.withDescription("Generate debug information")
|
||||
.withLongOpt("debug")
|
||||
|
@ -116,7 +108,6 @@ public final class TeaVMRunner {
|
|||
}
|
||||
|
||||
TeaVMTool tool = new TeaVMTool();
|
||||
tool.setBytecodeLogging(commandLine.hasOption("logbytecode"));
|
||||
if (commandLine.hasOption("d")) {
|
||||
tool.setTargetDirectory(new File(commandLine.getOptionValue("d")));
|
||||
}
|
||||
|
@ -269,7 +260,7 @@ public final class TeaVMRunner {
|
|||
case LINKING:
|
||||
System.out.print("Linking methods...");
|
||||
break;
|
||||
case DEVIRTUALIZATION:
|
||||
case OPTIMIZATION:
|
||||
System.out.print("Applying devirtualization...");
|
||||
break;
|
||||
case DECOMPILATION:
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2016 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.tooling;
|
||||
|
||||
public enum TeaVMTargetType {
|
||||
JAVASCRIPT
|
||||
}
|
|
@ -15,8 +15,24 @@
|
|||
*/
|
||||
package org.teavm.tooling;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.teavm.cache.DiskCachedClassHolderSource;
|
||||
import org.teavm.cache.DiskProgramCache;
|
||||
|
@ -27,26 +43,37 @@ import org.teavm.debugging.information.DebugInformationBuilder;
|
|||
import org.teavm.dependency.DependencyInfo;
|
||||
import org.teavm.diagnostics.ProblemProvider;
|
||||
import org.teavm.javascript.RenderingContext;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.javascript.target.JavaScriptTarget;
|
||||
import org.teavm.model.ClassHolderSource;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.PreOptimizingClassHolderSource;
|
||||
import org.teavm.model.ProgramReader;
|
||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||
import org.teavm.tooling.sources.SourceFileProvider;
|
||||
import org.teavm.tooling.sources.SourceFilesCopier;
|
||||
import org.teavm.vm.*;
|
||||
import org.teavm.vm.BuildTarget;
|
||||
import org.teavm.vm.DirectoryBuildTarget;
|
||||
import org.teavm.vm.TeaVM;
|
||||
import org.teavm.vm.TeaVMBuilder;
|
||||
import org.teavm.vm.TeaVMEntryPoint;
|
||||
import org.teavm.vm.TeaVMProgressListener;
|
||||
import org.teavm.vm.TeaVMTarget;
|
||||
import org.teavm.vm.spi.AbstractRendererListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TeaVMTool implements BaseTeaVMTool {
|
||||
private File targetDirectory = new File(".");
|
||||
private TeaVMTargetType targetType = TeaVMTargetType.JAVASCRIPT;
|
||||
private String targetFileName = "classes.js";
|
||||
private boolean minifying = true;
|
||||
private String mainClass;
|
||||
private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE;
|
||||
private Properties properties = new Properties();
|
||||
private boolean mainPageIncluded;
|
||||
private boolean bytecodeLogging;
|
||||
private boolean debugInformationGenerated;
|
||||
private boolean sourceMapsFileGenerated;
|
||||
private boolean sourceFilesCopied;
|
||||
|
@ -66,6 +93,8 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
private TeaVMProgressListener progressListener;
|
||||
private TeaVM vm;
|
||||
private List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
||||
private DebugInformationBuilder debugEmitter;
|
||||
private JavaScriptTarget javaScriptTarget;
|
||||
|
||||
public File getTargetDirectory() {
|
||||
return targetDirectory;
|
||||
|
@ -126,14 +155,6 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
this.mainPageIncluded = mainPageIncluded;
|
||||
}
|
||||
|
||||
public boolean isBytecodeLogging() {
|
||||
return bytecodeLogging;
|
||||
}
|
||||
|
||||
public void setBytecodeLogging(boolean bytecodeLogging) {
|
||||
this.bytecodeLogging = bytecodeLogging;
|
||||
}
|
||||
|
||||
public boolean isDebugInformationGenerated() {
|
||||
return debugInformationGenerated;
|
||||
}
|
||||
|
@ -262,11 +283,34 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
sourceFileProviders.add(sourceFileProvider);
|
||||
}
|
||||
|
||||
private TeaVMTarget prepareTarget() {
|
||||
switch (targetType) {
|
||||
case JAVASCRIPT:
|
||||
return prepareJavaScriptTarget();
|
||||
}
|
||||
throw new IllegalStateException("Unknown target type: " + targetType);
|
||||
}
|
||||
|
||||
private TeaVMTarget prepareJavaScriptTarget() {
|
||||
javaScriptTarget = new JavaScriptTarget();
|
||||
javaScriptTarget.setMinifying(minifying);
|
||||
|
||||
DebugInformationBuilder debugEmitter = debugInformationGenerated || sourceMapsFileGenerated
|
||||
? new DebugInformationBuilder() : null;
|
||||
javaScriptTarget.setDebugEmitter(debugEmitter);
|
||||
|
||||
if (incremental) {
|
||||
javaScriptTarget.setAstCache(astCache);
|
||||
}
|
||||
|
||||
return javaScriptTarget;
|
||||
}
|
||||
|
||||
public void generate() throws TeaVMToolException {
|
||||
try {
|
||||
cancelled = false;
|
||||
log.info("Building JavaScript file");
|
||||
TeaVMBuilder vmBuilder = new TeaVMBuilder();
|
||||
TeaVMBuilder vmBuilder = new TeaVMBuilder(prepareTarget());
|
||||
if (incremental) {
|
||||
cacheDirectory.mkdirs();
|
||||
symbolTable = new FileSymbolTable(new File(cacheDirectory, "symbols"));
|
||||
|
@ -276,7 +320,10 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
cachedClassSource = new DiskCachedClassHolderSource(cacheDirectory, symbolTable, fileTable,
|
||||
classSource, innerClassSource);
|
||||
programCache = new DiskProgramCache(cacheDirectory, symbolTable, fileTable, innerClassSource);
|
||||
|
||||
if (targetType == TeaVMTargetType.JAVASCRIPT) {
|
||||
astCache = new DiskRegularMethodNodeCache(cacheDirectory, symbolTable, fileTable, innerClassSource);
|
||||
}
|
||||
try {
|
||||
symbolTable.update();
|
||||
fileTable.update();
|
||||
|
@ -292,17 +339,11 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
if (progressListener != null) {
|
||||
vm.setProgressListener(progressListener);
|
||||
}
|
||||
vm.setMinifying(minifying);
|
||||
vm.setBytecodeLogging(bytecodeLogging);
|
||||
|
||||
vm.setProperties(properties);
|
||||
DebugInformationBuilder debugEmitter = debugInformationGenerated || sourceMapsFileGenerated
|
||||
? new DebugInformationBuilder() : null;
|
||||
vm.setDebugEmitter(debugEmitter);
|
||||
vm.setIncremental(incremental);
|
||||
if (incremental) {
|
||||
vm.setAstCache(astCache);
|
||||
vm.setProgramCache(programCache);
|
||||
}
|
||||
vm.setIncremental(incremental);
|
||||
|
||||
vm.installPlugins();
|
||||
for (ClassHolderTransformer transformer : transformers) {
|
||||
vm.add(transformer);
|
||||
|
@ -336,30 +377,55 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
}
|
||||
}
|
||||
targetDirectory.mkdirs();
|
||||
try (Writer writer = new OutputStreamWriter(new BufferedOutputStream(
|
||||
new FileOutputStream(new File(targetDirectory, targetFileName)), 65536), "UTF-8")) {
|
||||
try (OutputStream output = new BufferedOutputStream(
|
||||
new FileOutputStream(new File(targetDirectory, targetFileName)), 65536)) {
|
||||
Writer writer = new OutputStreamWriter(output, "UTF-8");
|
||||
if (runtime == RuntimeCopyOperation.MERGED) {
|
||||
vm.add(runtimeInjector);
|
||||
javaScriptTarget.add(runtimeInjector);
|
||||
}
|
||||
vm.build(writer, new DirectoryBuildTarget(targetDirectory));
|
||||
vm.build(output, new DirectoryBuildTarget(targetDirectory));
|
||||
if (vm.wasCancelled()) {
|
||||
log.info("Build cancelled");
|
||||
cancelled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ProblemProvider problemProvider = vm.getProblemProvider();
|
||||
if (problemProvider.getProblems().isEmpty()) {
|
||||
log.info("Output file successfully built");
|
||||
} else if (problemProvider.getSevereProblems().isEmpty()) {
|
||||
log.info("Output file built with warnings");
|
||||
TeaVMProblemRenderer.describeProblems(vm, log);
|
||||
} else {
|
||||
log.info("Output file built with errors");
|
||||
TeaVMProblemRenderer.describeProblems(vm, log);
|
||||
}
|
||||
|
||||
if (targetType == TeaVMTargetType.JAVASCRIPT) {
|
||||
additionalJavaScriptOutput(writer);
|
||||
}
|
||||
|
||||
if (incremental) {
|
||||
programCache.flush();
|
||||
if (astCache != null) {
|
||||
astCache.flush();
|
||||
}
|
||||
cachedClassSource.flush();
|
||||
symbolTable.flush();
|
||||
fileTable.flush();
|
||||
log.info("Cache updated");
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new TeaVMToolException("IO error occured", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void additionalJavaScriptOutput(Writer writer) throws IOException {
|
||||
if (mainClass != null) {
|
||||
writer.append("main = $rt_mainStarter(main);\n");
|
||||
}
|
||||
ProblemProvider problemProvider = vm.getProblemProvider();
|
||||
if (problemProvider.getProblems().isEmpty()) {
|
||||
log.info("JavaScript file successfully built");
|
||||
} else if (problemProvider.getSevereProblems().isEmpty()) {
|
||||
log.info("JavaScript file built with warnings");
|
||||
TeaVMProblemRenderer.describeProblems(vm, log);
|
||||
} else {
|
||||
log.info("JavaScript file built with errors");
|
||||
TeaVMProblemRenderer.describeProblems(vm, log);
|
||||
}
|
||||
|
||||
if (debugInformationGenerated) {
|
||||
assert debugEmitter != null;
|
||||
DebugInformation debugInfo = debugEmitter.getDebugInformation();
|
||||
|
@ -384,15 +450,7 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
copySourceFiles();
|
||||
log.info("Source files successfully written");
|
||||
}
|
||||
if (incremental) {
|
||||
programCache.flush();
|
||||
astCache.flush();
|
||||
cachedClassSource.flush();
|
||||
symbolTable.flush();
|
||||
fileTable.flush();
|
||||
log.info("Cache updated");
|
||||
}
|
||||
}
|
||||
|
||||
if (runtime == RuntimeCopyOperation.SEPARATE) {
|
||||
resourceToFile("org/teavm/javascript/runtime.js", "runtime.js");
|
||||
}
|
||||
|
@ -403,13 +461,10 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
text = IOUtils.toString(reader).replace("${classes.js}", targetFileName);
|
||||
}
|
||||
File mainPageFile = new File(targetDirectory, "main.html");
|
||||
try (Writer writer = new OutputStreamWriter(new FileOutputStream(mainPageFile), "UTF-8")) {
|
||||
writer.append(text);
|
||||
try (Writer mainPageWriter = new OutputStreamWriter(new FileOutputStream(mainPageFile), "UTF-8")) {
|
||||
mainPageWriter.append(text);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new TeaVMToolException("IO error occured", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void copySourceFiles() {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<property key="Bundle-Description" value="TeaVM API that helps to create tooling" />
|
||||
<property key="Export-Package" value="org.teavm.*" />
|
||||
<property key="Bundle-Name" value="TeaVM tooling core" />
|
||||
<property key="Include-Resource" value="org/teavm/tooling/main.html=$MODULE_DIR$/src/main/resources/org/teavm/tooling/main.html,org/teavm/tooling/test/junit.html=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/junit.html,org/teavm/tooling/test/junit-client.html=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/junit-client.html,org/teavm/tooling/test/res/junit-support.js=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/junit-support.js,org/teavm/tooling/test/res/control-000-small.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/control-000-small.png,org/teavm/tooling/test/res/package_obj.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/package_obj.png,org/teavm/tooling/test/res/junit-client.js=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/junit-client.js,org/teavm/tooling/test/res/junit.css=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/junit.css,org/teavm/tooling/test/res/tick-small-red.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/tick-small-red.png,org/teavm/tooling/test/res/tick-small.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/tick-small.png,org/teavm/tooling/test/res/class_obj.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/class_obj.png,org/teavm/tooling/test/res/toggle-small.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/toggle-small.png,org/teavm/tooling/test/res/toggle-small-expand.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/toggle-small-expand.png,org/teavm/tooling/test/res/methpub_obj.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/methpub_obj.png" />
|
||||
<property key="Include-Resource" value="org/teavm/tooling/test/junit.html=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/junit.html,org/teavm/tooling/test/junit-client.html=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/junit-client.html,org/teavm/tooling/test/res/tick-small-red.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/tick-small-red.png,org/teavm/tooling/test/res/class_obj.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/class_obj.png,org/teavm/tooling/test/res/junit.css=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/junit.css,org/teavm/tooling/test/res/junit-client.js=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/junit-client.js,org/teavm/tooling/test/res/methpub_obj.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/methpub_obj.png,org/teavm/tooling/test/res/tick-small.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/tick-small.png,org/teavm/tooling/test/res/control-000-small.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/control-000-small.png,org/teavm/tooling/test/res/junit-support.js=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/junit-support.js,org/teavm/tooling/test/res/package_obj.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/package_obj.png,org/teavm/tooling/test/res/toggle-small.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/toggle-small.png,org/teavm/tooling/test/res/toggle-small-expand.png=$MODULE_DIR$/src/main/resources/org/teavm/tooling/test/res/toggle-small-expand.png,org/teavm/tooling/main.html=$MODULE_DIR$/src/main/resources/org/teavm/tooling/main.html" />
|
||||
</additionalProperties>
|
||||
<additionalJARContents />
|
||||
</configuration>
|
||||
|
|
|
@ -20,8 +20,6 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
|
@ -49,6 +47,7 @@ import org.junit.runners.model.InitializationError;
|
|||
import org.teavm.callgraph.CallGraph;
|
||||
import org.teavm.diagnostics.DefaultProblemTextConsumer;
|
||||
import org.teavm.diagnostics.Problem;
|
||||
import org.teavm.javascript.target.JavaScriptTarget;
|
||||
import org.teavm.model.ClassHolder;
|
||||
import org.teavm.model.ClassHolderSource;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
|
@ -345,12 +344,13 @@ public class TeaVMTestRunner extends Runner {
|
|||
MethodHolder methodHolder = classHolder.getMethod(getDescriptor(method));
|
||||
Class<?> runnerType = testAdapter.getRunner(methodHolder);
|
||||
|
||||
TeaVM vm = new TeaVMBuilder()
|
||||
JavaScriptTarget jsTarget = new JavaScriptTarget();
|
||||
jsTarget.setMinifying(false);
|
||||
TeaVM vm = new TeaVMBuilder(jsTarget)
|
||||
.setClassLoader(classLoader)
|
||||
.setClassSource(classSource)
|
||||
.build();
|
||||
vm.setIncremental(false);
|
||||
vm.setMinifying(false);
|
||||
vm.installPlugins();
|
||||
|
||||
new TestExceptionPlugin().install(vm);
|
||||
|
@ -360,7 +360,7 @@ public class TeaVMTestRunner extends Runner {
|
|||
applyProperties(method.getDeclaringClass(), properties);
|
||||
vm.setProperties(properties);
|
||||
|
||||
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8")) {
|
||||
try (OutputStream innerWriter = new FileOutputStream(outputFile)) {
|
||||
MethodReference exceptionMsg = new MethodReference(ExceptionHelper.class, "showException",
|
||||
Throwable.class, String.class);
|
||||
vm.entryPoint("runTest", new MethodReference(TestEntryPoint.class, "run", void.class)).async();
|
||||
|
|
|
@ -55,9 +55,6 @@ public class BuildJavascriptMojo extends AbstractJavascriptMojo {
|
|||
@Parameter
|
||||
private boolean mainPageIncluded;
|
||||
|
||||
@Parameter
|
||||
private boolean bytecodeLogging;
|
||||
|
||||
@Parameter
|
||||
private ClassAlias[] classAliases;
|
||||
|
||||
|
@ -86,7 +83,6 @@ public class BuildJavascriptMojo extends AbstractJavascriptMojo {
|
|||
setupTool(tool);
|
||||
tool.setLog(new MavenTeaVMToolLog(log));
|
||||
try {
|
||||
tool.setBytecodeLogging(bytecodeLogging);
|
||||
tool.setMainClass(mainClass);
|
||||
tool.setMainPageIncluded(mainPageIncluded);
|
||||
tool.setRuntime(runtime);
|
||||
|
|
Loading…
Reference in New Issue
Block a user