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.lambda.LambdaMetafactorySubstitutor;
|
||||||
import org.teavm.classlib.impl.unicode.CLDRReader;
|
import org.teavm.classlib.impl.unicode.CLDRReader;
|
||||||
import org.teavm.classlib.java.lang.reflect.AnnotationDependencyListener;
|
import org.teavm.classlib.java.lang.reflect.AnnotationDependencyListener;
|
||||||
|
import org.teavm.javascript.target.TeaVMJavaScriptHost;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.platform.PlatformClass;
|
import org.teavm.platform.PlatformClass;
|
||||||
import org.teavm.vm.spi.TeaVMHost;
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
import org.teavm.vm.spi.TeaVMPlugin;
|
import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class JCLPlugin implements TeaVMPlugin {
|
public class JCLPlugin implements TeaVMPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void install(TeaVMHost host) {
|
public void install(TeaVMHost host) {
|
||||||
|
@ -40,7 +37,11 @@ public class JCLPlugin implements TeaVMPlugin {
|
||||||
host.add(serviceLoaderSupp);
|
host.add(serviceLoaderSupp);
|
||||||
MethodReference loadServicesMethod = new MethodReference(ServiceLoader.class, "loadServices",
|
MethodReference loadServicesMethod = new MethodReference(ServiceLoader.class, "loadServices",
|
||||||
PlatformClass.class, Object[].class);
|
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();
|
JavacSupport javacSupport = new JavacSupport();
|
||||||
host.add(javacSupport);
|
host.add(javacSupport);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<property key="Bundle-Description" value="TeaVM Java class library emulation" />
|
<property key="Bundle-Description" value="TeaVM Java class library emulation" />
|
||||||
<property key="Export-Package" value="org.teavm.classlib.*" />
|
<property key="Export-Package" value="org.teavm.classlib.*" />
|
||||||
<property key="Bundle-Name" value="TeaVM Java class library" />
|
<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>
|
</additionalProperties>
|
||||||
<additionalJARContents />
|
<additionalJARContents />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -18,10 +18,6 @@ package org.teavm.debugging.information;
|
||||||
import org.teavm.codegen.LocationProvider;
|
import org.teavm.codegen.LocationProvider;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public interface DebugInformationEmitter {
|
public interface DebugInformationEmitter {
|
||||||
void setLocationProvider(LocationProvider locationProvider);
|
void setLocationProvider(LocationProvider locationProvider);
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,6 @@ package org.teavm.vm;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public interface BuildTarget {
|
public interface BuildTarget {
|
||||||
OutputStream createResource(String fileName) throws IOException;
|
OutputStream createResource(String fileName) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,58 +19,32 @@ import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.io.Writer;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.Set;
|
import java.util.stream.Collectors;
|
||||||
import org.teavm.cache.NoCache;
|
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.common.ServiceRepository;
|
||||||
import org.teavm.debugging.information.DebugInformationEmitter;
|
|
||||||
import org.teavm.debugging.information.SourceLocation;
|
|
||||||
import org.teavm.dependency.BootstrapMethodSubstitutor;
|
import org.teavm.dependency.BootstrapMethodSubstitutor;
|
||||||
import org.teavm.dependency.DependencyChecker;
|
import org.teavm.dependency.DependencyChecker;
|
||||||
import org.teavm.dependency.DependencyInfo;
|
import org.teavm.dependency.DependencyInfo;
|
||||||
import org.teavm.dependency.DependencyListener;
|
import org.teavm.dependency.DependencyListener;
|
||||||
import org.teavm.dependency.Linker;
|
import org.teavm.dependency.Linker;
|
||||||
import org.teavm.dependency.MethodDependency;
|
|
||||||
import org.teavm.diagnostics.AccumulationDiagnostics;
|
import org.teavm.diagnostics.AccumulationDiagnostics;
|
||||||
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.diagnostics.ProblemProvider;
|
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.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.ClassHolder;
|
||||||
import org.teavm.model.ClassHolderSource;
|
import org.teavm.model.ClassHolderSource;
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.ClassReaderSource;
|
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.ListableClassHolderSource;
|
||||||
import org.teavm.model.ListableClassReaderSource;
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
import org.teavm.model.MethodHolder;
|
import org.teavm.model.MethodHolder;
|
||||||
|
@ -78,15 +52,6 @@ import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.MutableClassHolderSource;
|
import org.teavm.model.MutableClassHolderSource;
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
import org.teavm.model.ProgramCache;
|
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.MissingItemsProcessor;
|
||||||
import org.teavm.model.util.ModelUtils;
|
import org.teavm.model.util.ModelUtils;
|
||||||
import org.teavm.model.util.ProgramUtils;
|
import org.teavm.model.util.ProgramUtils;
|
||||||
|
@ -103,8 +68,8 @@ import org.teavm.optimization.MethodOptimization;
|
||||||
import org.teavm.optimization.RedundantJumpElimination;
|
import org.teavm.optimization.RedundantJumpElimination;
|
||||||
import org.teavm.optimization.UnreachableBasicBlockElimination;
|
import org.teavm.optimization.UnreachableBasicBlockElimination;
|
||||||
import org.teavm.optimization.UnusedVariableElimination;
|
import org.teavm.optimization.UnusedVariableElimination;
|
||||||
import org.teavm.vm.spi.RendererListener;
|
|
||||||
import org.teavm.vm.spi.TeaVMHost;
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
|
import org.teavm.vm.spi.TeaVMHostExtension;
|
||||||
import org.teavm.vm.spi.TeaVMPlugin;
|
import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,29 +106,24 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
private final DependencyChecker dependencyChecker;
|
private final DependencyChecker dependencyChecker;
|
||||||
private final AccumulationDiagnostics diagnostics = new AccumulationDiagnostics();
|
private final AccumulationDiagnostics diagnostics = new AccumulationDiagnostics();
|
||||||
private final ClassLoader classLoader;
|
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> entryPoints = new HashMap<>();
|
||||||
|
private final Map<String, TeaVMEntryPoint> readonlyEntryPoints = Collections.unmodifiableMap(entryPoints);
|
||||||
private final Map<String, String> exportedClasses = new HashMap<>();
|
private final Map<String, String> exportedClasses = new HashMap<>();
|
||||||
private final Map<MethodReference, Generator> methodGenerators = new HashMap<>();
|
private final Map<String, String> readonlyExportedClasses = Collections.unmodifiableMap(exportedClasses);
|
||||||
private final Map<MethodReference, Injector> methodInjectors = new HashMap<>();
|
|
||||||
private final List<RendererListener> rendererListeners = new ArrayList<>();
|
|
||||||
private final Map<Class<?>, Object> services = new HashMap<>();
|
private final Map<Class<?>, Object> services = new HashMap<>();
|
||||||
private final Properties properties = new Properties();
|
private final Properties properties = new Properties();
|
||||||
private DebugInformationEmitter debugEmitter;
|
|
||||||
private ProgramCache programCache;
|
private ProgramCache programCache;
|
||||||
private MethodNodeCache astCache = new EmptyRegularMethodNodeCache();
|
|
||||||
private boolean incremental;
|
private boolean incremental;
|
||||||
private TeaVMProgressListener progressListener;
|
private TeaVMProgressListener progressListener;
|
||||||
private boolean cancelled;
|
private boolean cancelled;
|
||||||
private ListableClassHolderSource writtenClasses;
|
private ListableClassHolderSource writtenClasses;
|
||||||
private final Set<MethodReference> asyncMethods = new HashSet<>();
|
private TeaVMTarget target;
|
||||||
private final Set<MethodReference> asyncFamilyMethods = new HashSet<>();
|
private Map<Class<?>, TeaVMHostExtension> extensions = new HashMap<>();
|
||||||
|
|
||||||
TeaVM(ClassReaderSource classSource, ClassLoader classLoader) {
|
TeaVM(TeaVMBuilder builder) {
|
||||||
this.classSource = classSource;
|
target = builder.target;
|
||||||
this.classLoader = classLoader;
|
classSource = builder.classSource;
|
||||||
|
classLoader = builder.classLoader;
|
||||||
dependencyChecker = new DependencyChecker(this.classSource, classLoader, this, diagnostics);
|
dependencyChecker = new DependencyChecker(this.classSource, classLoader, this, diagnostics);
|
||||||
progressListener = new TeaVMProgressListener() {
|
progressListener = new TeaVMProgressListener() {
|
||||||
@Override public TeaVMProgressFeedback progressReached(int progress) {
|
@Override public TeaVMProgressFeedback progressReached(int progress) {
|
||||||
|
@ -173,6 +133,12 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
return TeaVMProgressFeedback.CONTINUE;
|
return TeaVMProgressFeedback.CONTINUE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (TeaVMHostExtension extension : target.getHostExtensions()) {
|
||||||
|
for (Class<?> extensionType : getExtensionTypes(extension)) {
|
||||||
|
extensions.put(extensionType, extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -185,59 +151,16 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
dependencyChecker.addClassTransformer(transformer);
|
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
|
@Override
|
||||||
public void add(MethodReference methodRef, BootstrapMethodSubstitutor substitutor) {
|
public void add(MethodReference methodRef, BootstrapMethodSubstitutor substitutor) {
|
||||||
dependencyChecker.addBootstrapMethodSubstitutor(methodRef, substitutor);
|
dependencyChecker.addBootstrapMethodSubstitutor(methodRef, substitutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(RendererListener listener) {
|
|
||||||
rendererListeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return classLoader;
|
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
|
* Specifies configuration properties for TeaVM and its plugins. You should call this method before
|
||||||
* installing any plugins or interceptors.
|
* installing any plugins or interceptors.
|
||||||
|
@ -257,14 +180,6 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
return new Properties(properties);
|
return new Properties(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodNodeCache getAstCache() {
|
|
||||||
return astCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAstCache(MethodNodeCache methodAstCache) {
|
|
||||||
this.astCache = methodAstCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProgramCache getProgramCache() {
|
public ProgramCache getProgramCache() {
|
||||||
return programCache;
|
return programCache;
|
||||||
}
|
}
|
||||||
|
@ -391,14 +306,6 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
return writtenClasses;
|
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
|
* <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)
|
* 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
|
* actual generation happens and no exceptions thrown, but you can further call
|
||||||
* {@link #getProblemProvider()} to learn the build state.</p>
|
* {@link #getProblemProvider()} to learn the build state.</p>
|
||||||
*
|
*
|
||||||
* @param writer where to generate JavaScript. Should not be null.
|
* @param output where to generate JavaScript. Should not be null.
|
||||||
* @param target where to generate additional resources. Can be null, but if there are
|
* @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.
|
* plugins or inteceptors that generate additional resources, the build process will fail.
|
||||||
*
|
*
|
||||||
* @throws RenderingException when something went wrong during rendering phase.
|
* @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
|
// Check dependencies
|
||||||
reportPhase(TeaVMPhase.DEPENDENCY_CHECKING, 1);
|
reportPhase(TeaVMPhase.DEPENDENCY_CHECKING, 1);
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AliasProvider aliasProvider = minifying ? new MinifyingAliasProvider() : new DefaultAliasProvider();
|
|
||||||
dependencyChecker.setInterruptor(() -> progressListener.progressReached(0) == TeaVMProgressFeedback.CONTINUE);
|
dependencyChecker.setInterruptor(() -> progressListener.progressReached(0) == TeaVMProgressFeedback.CONTINUE);
|
||||||
dependencyChecker.linkMethod(new MethodReference(Class.class.getName(), "getClass",
|
target.contributeDependencies(dependencyChecker);
|
||||||
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"));
|
|
||||||
dependencyChecker.processDependencies();
|
dependencyChecker.processDependencies();
|
||||||
if (wasCancelled() || !diagnostics.getSevereProblems().isEmpty()) {
|
if (wasCancelled() || !diagnostics.getSevereProblems().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -469,73 +347,27 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimize and allocate registers
|
// Optimize and allocate registers
|
||||||
|
reportPhase(TeaVMPhase.OPTIMIZATION, 1);
|
||||||
|
|
||||||
if (!incremental) {
|
if (!incremental) {
|
||||||
devirtualize(classSet, dependencyChecker);
|
devirtualize(classSet, dependencyChecker);
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline(classSet);
|
||||||
|
if (wasCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ClassNode> clsNodes = modelToAst(classSet);
|
optimize(classSet);
|
||||||
|
|
||||||
// Render
|
|
||||||
reportPhase(TeaVMPhase.RENDERING, classSet.getClassNames().size());
|
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, dependencyChecker.getClassSource());
|
|
||||||
SourceWriterBuilder builder = new SourceWriterBuilder(naming);
|
// Render
|
||||||
builder.setMinified(minifying);
|
target.emit(classSet, output, buildTarget);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
@ -568,38 +400,11 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reportProgress(int progress) {
|
private void devirtualize(ListableClassHolderSource classes, DependencyInfo dependency) {
|
||||||
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()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Devirtualization devirtualization = new Devirtualization(dependency, classes);
|
Devirtualization devirtualization = new Devirtualization(dependency, classes);
|
||||||
int index = 0;
|
|
||||||
for (String className : classes.getClassNames()) {
|
for (String className : classes.getClassNames()) {
|
||||||
ClassHolder cls = classes.get(className);
|
ClassHolder cls = classes.get(className);
|
||||||
for (final MethodHolder method : cls.getMethods()) {
|
for (final MethodHolder method : cls.getMethods()) {
|
||||||
|
@ -607,12 +412,13 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
devirtualization.apply(method);
|
devirtualization.apply(method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reportProgress(++index);
|
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inline(ListableClassHolderSource classes) {
|
||||||
Inlining inlining = new Inlining();
|
Inlining inlining = new Inlining();
|
||||||
for (String className : classes.getClassNames()) {
|
for (String className : classes.getClassNames()) {
|
||||||
ClassHolder cls = classes.get(className);
|
ClassHolder cls = classes.get(className);
|
||||||
|
@ -621,90 +427,22 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
inlining.apply(method.getProgram(), classes);
|
inlining.apply(method.getProgram(), classes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reportProgress(++index);
|
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ClassNode> modelToAst(ListableClassHolderSource classes) {
|
private void optimize(ListableClassHolderSource classSource) {
|
||||||
AsyncMethodFinder asyncFinder = new AsyncMethodFinder(dependencyChecker.getCallGraph(), diagnostics);
|
for (String className : classSource.getClassNames()) {
|
||||||
asyncFinder.find(classes);
|
ClassHolder cls = classSource.get(className);
|
||||||
asyncMethods.addAll(asyncFinder.getAsyncMethods());
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
asyncFamilyMethods.addAll(asyncFinder.getAsyncFamilyMethods());
|
processMethod(method);
|
||||||
|
}
|
||||||
progressListener.phaseStarted(TeaVMPhase.DECOMPILATION, classes.getClassNames().size());
|
if (wasCancelled()) {
|
||||||
Decompiler decompiler = new Decompiler(classes, classLoader, asyncMethods, asyncFamilyMethods);
|
return;
|
||||||
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);
|
|
||||||
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) {
|
|
||||||
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) {
|
private void processMethod(MethodHolder method) {
|
||||||
|
@ -725,8 +463,11 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
changed |= optimization.optimize(method, optimizedProgram);
|
changed |= optimization.optimize(method, optimizedProgram);
|
||||||
}
|
}
|
||||||
} while (changed);
|
} while (changed);
|
||||||
RegisterAllocator allocator = new RegisterAllocator();
|
|
||||||
allocator.allocateRegisters(method, optimizedProgram);
|
if (target.requiresRegisterAllocation()) {
|
||||||
|
RegisterAllocator allocator = new RegisterAllocator();
|
||||||
|
allocator.allocateRegisters(method, optimizedProgram);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (incremental && programCache != null) {
|
if (incremental && programCache != null) {
|
||||||
programCache.store(method.getReference(), optimizedProgram);
|
programCache.store(method.getReference(), optimizedProgram);
|
||||||
|
@ -749,102 +490,9 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
new UnreachableBasicBlockElimination());
|
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 {
|
public void build(File dir, String fileName) throws RenderingException {
|
||||||
try (Writer writer = new OutputStreamWriter(new FileOutputStream(new File(dir, fileName)), "UTF-8")) {
|
try (OutputStream output = new FileOutputStream(new File(dir, fileName))) {
|
||||||
build(writer, new DirectoryBuildTarget(dir));
|
build(output, new DirectoryBuildTarget(dir));
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new RuntimeException("Platform does not support UTF-8", e);
|
throw new RuntimeException("Platform does not support UTF-8", e);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -877,4 +525,69 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
public <T> void registerService(Class<T> type, T instance) {
|
public <T> void registerService(Class<T> type, T instance) {
|
||||||
services.put(type, 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.model.ClassHolderSource;
|
||||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class TeaVMBuilder {
|
public class TeaVMBuilder {
|
||||||
|
TeaVMTarget target;
|
||||||
ClassHolderSource classSource;
|
ClassHolderSource classSource;
|
||||||
ClassLoader classLoader;
|
ClassLoader classLoader;
|
||||||
|
|
||||||
public TeaVMBuilder() {
|
public TeaVMBuilder(TeaVMTarget target) {
|
||||||
|
this.target = target;
|
||||||
classLoader = TeaVMBuilder.class.getClassLoader();
|
classLoader = TeaVMBuilder.class.getClassLoader();
|
||||||
classSource = new ClasspathClassHolderSource(classLoader);
|
classSource = new ClasspathClassHolderSource(classLoader);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +48,6 @@ public class TeaVMBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TeaVM build() {
|
public TeaVM build() {
|
||||||
return new TeaVM(classSource, classLoader);
|
return new TeaVM(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,10 @@ public class TeaVMEntryPoint {
|
||||||
method.use();
|
method.use();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MethodReference getReference() {
|
||||||
|
return reference;
|
||||||
|
}
|
||||||
|
|
||||||
String getPublicName() {
|
String getPublicName() {
|
||||||
return publicName;
|
return publicName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.vm;
|
package org.teavm.vm;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public enum TeaVMPhase {
|
public enum TeaVMPhase {
|
||||||
DEPENDENCY_CHECKING,
|
DEPENDENCY_CHECKING,
|
||||||
LINKING,
|
LINKING,
|
||||||
DEVIRTUALIZATION,
|
OPTIMIZATION,
|
||||||
DECOMPILATION,
|
DECOMPILATION,
|
||||||
RENDERING
|
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 java.util.Properties;
|
||||||
import org.teavm.dependency.BootstrapMethodSubstitutor;
|
import org.teavm.dependency.BootstrapMethodSubstitutor;
|
||||||
import org.teavm.dependency.DependencyListener;
|
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.ClassHolderTransformer;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.vm.TeaVM;
|
import org.teavm.vm.TeaVM;
|
||||||
|
@ -36,13 +34,9 @@ public interface TeaVMHost {
|
||||||
|
|
||||||
void add(ClassHolderTransformer classTransformer);
|
void add(ClassHolderTransformer classTransformer);
|
||||||
|
|
||||||
void add(MethodReference methodRef, Generator generator);
|
|
||||||
|
|
||||||
void add(MethodReference methodRef, Injector injector);
|
|
||||||
|
|
||||||
void add(MethodReference methodRef, BootstrapMethodSubstitutor substitutor);
|
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);
|
<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;
|
package org.teavm.vm.spi;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public interface TeaVMPlugin {
|
public interface TeaVMPlugin {
|
||||||
void install(TeaVMHost host);
|
void install(TeaVMHost host);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,19 +15,20 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.html4j;
|
package org.teavm.html4j;
|
||||||
|
|
||||||
|
import org.teavm.javascript.target.TeaVMJavaScriptHost;
|
||||||
import org.teavm.vm.spi.TeaVMHost;
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
import org.teavm.vm.spi.TeaVMPlugin;
|
import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class HTML4JPlugin implements TeaVMPlugin {
|
public class HTML4JPlugin implements TeaVMPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void install(TeaVMHost host) {
|
public void install(TeaVMHost host) {
|
||||||
|
if (host.getExtension(TeaVMJavaScriptHost.class) == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
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());
|
|
||||||
|
host.getExtension(TeaVMJavaScriptHost.class).add(new JavaScriptResourceInterceptor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,22 +15,23 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.jso.impl;
|
package org.teavm.jso.impl;
|
||||||
|
|
||||||
|
import org.teavm.javascript.target.TeaVMJavaScriptHost;
|
||||||
import org.teavm.vm.spi.TeaVMHost;
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
import org.teavm.vm.spi.TeaVMPlugin;
|
import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class JSOPlugin implements TeaVMPlugin {
|
public class JSOPlugin implements TeaVMPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void install(TeaVMHost host) {
|
public void install(TeaVMHost host) {
|
||||||
|
if (host.getExtension(TeaVMJavaScriptHost.class) == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
JSBodyRepository repository = new JSBodyRepository();
|
JSBodyRepository repository = new JSBodyRepository();
|
||||||
host.registerService(JSBodyRepository.class, repository);
|
host.registerService(JSBodyRepository.class, repository);
|
||||||
host.add(new JSObjectClassTransformer(repository));
|
host.add(new JSObjectClassTransformer(repository));
|
||||||
JSDependencyListener dependencyListener = new JSDependencyListener(repository);
|
JSDependencyListener dependencyListener = new JSDependencyListener(repository);
|
||||||
JSAliasRenderer aliasRenderer = new JSAliasRenderer(dependencyListener);
|
JSAliasRenderer aliasRenderer = new JSAliasRenderer(dependencyListener);
|
||||||
host.add(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.TeaVMHost;
|
||||||
import org.teavm.vm.spi.TeaVMPlugin;
|
import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class PlatformPlugin implements TeaVMPlugin {
|
public class PlatformPlugin implements TeaVMPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void install(TeaVMHost host) {
|
public void install(TeaVMHost host) {
|
||||||
|
|
|
@ -16,18 +16,15 @@
|
||||||
package org.teavm.platform.plugin;
|
package org.teavm.platform.plugin;
|
||||||
|
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
|
import org.teavm.javascript.target.TeaVMJavaScriptHost;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.vm.spi.TeaVMHost;
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
class ResourceAccessorTransformer implements ClassHolderTransformer {
|
class ResourceAccessorTransformer implements ClassHolderTransformer {
|
||||||
private TeaVMHost vm;
|
private TeaVMJavaScriptHost vm;
|
||||||
|
|
||||||
public ResourceAccessorTransformer(TeaVMHost vm) {
|
public ResourceAccessorTransformer(TeaVMHost vm) {
|
||||||
this.vm = vm;
|
this.vm = vm.getExtension(TeaVMJavaScriptHost.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -17,7 +17,9 @@ package org.teavm.dependency;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.teavm.javascript.target.JavaScriptTarget;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.tooling.TeaVMProblemRenderer;
|
import org.teavm.tooling.TeaVMProblemRenderer;
|
||||||
|
@ -73,10 +75,10 @@ public class ClassValueTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private DependencyInfo runTest(String methodName) {
|
private DependencyInfo runTest(String methodName) {
|
||||||
TeaVM vm = new TeaVMBuilder().build();
|
TeaVM vm = new TeaVMBuilder(new JavaScriptTarget()).build();
|
||||||
vm.installPlugins();
|
vm.installPlugins();
|
||||||
vm.entryPoint(new MethodReference(getClass().getName(), methodName, ValueType.VOID));
|
vm.entryPoint(new MethodReference(getClass().getName(), methodName, ValueType.VOID));
|
||||||
vm.build(new StringBuilder(), null);
|
vm.build(new ByteArrayOutputStream(), null);
|
||||||
if (!vm.getProblemProvider().getSevereProblems().isEmpty()) {
|
if (!vm.getProblemProvider().getSevereProblems().isEmpty()) {
|
||||||
fail("Code compiled with errors:\n" + describeProblems(vm));
|
fail("Code compiled with errors:\n" + describeProblems(vm));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,15 +15,15 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.tests;
|
package org.teavm.tests;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.teavm.diagnostics.Problem;
|
import org.teavm.diagnostics.Problem;
|
||||||
|
import org.teavm.javascript.target.JavaScriptTarget;
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSBody;
|
||||||
import org.teavm.junit.SkipJVM;
|
|
||||||
import org.teavm.junit.TeaVMTestRunner;
|
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
import org.teavm.vm.TeaVM;
|
import org.teavm.vm.TeaVM;
|
||||||
|
@ -96,10 +96,10 @@ public class JSOTest {
|
||||||
private static native Object jsBodyWithWrongReturningType(String value);
|
private static native Object jsBodyWithWrongReturningType(String value);
|
||||||
|
|
||||||
private List<Problem> build(String methodName) {
|
private List<Problem> build(String methodName) {
|
||||||
TeaVM vm = new TeaVMBuilder().build();
|
TeaVM vm = new TeaVMBuilder(new JavaScriptTarget()).build();
|
||||||
vm.installPlugins();
|
vm.installPlugins();
|
||||||
vm.entryPoint("org/teavm/metaprogramming/test", new MethodReference(JSOTest.class, methodName, void.class));
|
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();
|
return vm.getProblemProvider().getSevereProblems();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,6 @@ import org.teavm.vm.TeaVMPhase;
|
||||||
import org.teavm.vm.TeaVMProgressFeedback;
|
import org.teavm.vm.TeaVMProgressFeedback;
|
||||||
import org.teavm.vm.TeaVMProgressListener;
|
import org.teavm.vm.TeaVMProgressListener;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public final class TeaVMRunner {
|
public final class TeaVMRunner {
|
||||||
private static long startTime;
|
private static long startTime;
|
||||||
private static long phaseStartTime;
|
private static long phaseStartTime;
|
||||||
|
@ -69,10 +65,6 @@ public final class TeaVMRunner {
|
||||||
.withDescription("causes TeaVM to include default main page")
|
.withDescription("causes TeaVM to include default main page")
|
||||||
.withLongOpt("mainpage")
|
.withLongOpt("mainpage")
|
||||||
.create());
|
.create());
|
||||||
options.addOption(OptionBuilder
|
|
||||||
.withDescription("causes TeaVM to log bytecode")
|
|
||||||
.withLongOpt("logbytecode")
|
|
||||||
.create());
|
|
||||||
options.addOption(OptionBuilder
|
options.addOption(OptionBuilder
|
||||||
.withDescription("Generate debug information")
|
.withDescription("Generate debug information")
|
||||||
.withLongOpt("debug")
|
.withLongOpt("debug")
|
||||||
|
@ -116,7 +108,6 @@ public final class TeaVMRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
TeaVMTool tool = new TeaVMTool();
|
TeaVMTool tool = new TeaVMTool();
|
||||||
tool.setBytecodeLogging(commandLine.hasOption("logbytecode"));
|
|
||||||
if (commandLine.hasOption("d")) {
|
if (commandLine.hasOption("d")) {
|
||||||
tool.setTargetDirectory(new File(commandLine.getOptionValue("d")));
|
tool.setTargetDirectory(new File(commandLine.getOptionValue("d")));
|
||||||
}
|
}
|
||||||
|
@ -269,7 +260,7 @@ public final class TeaVMRunner {
|
||||||
case LINKING:
|
case LINKING:
|
||||||
System.out.print("Linking methods...");
|
System.out.print("Linking methods...");
|
||||||
break;
|
break;
|
||||||
case DEVIRTUALIZATION:
|
case OPTIMIZATION:
|
||||||
System.out.print("Applying devirtualization...");
|
System.out.print("Applying devirtualization...");
|
||||||
break;
|
break;
|
||||||
case DECOMPILATION:
|
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;
|
package org.teavm.tooling;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.BufferedOutputStream;
|
||||||
import java.util.*;
|
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.apache.commons.io.IOUtils;
|
||||||
import org.teavm.cache.DiskCachedClassHolderSource;
|
import org.teavm.cache.DiskCachedClassHolderSource;
|
||||||
import org.teavm.cache.DiskProgramCache;
|
import org.teavm.cache.DiskProgramCache;
|
||||||
|
@ -27,26 +43,37 @@ import org.teavm.debugging.information.DebugInformationBuilder;
|
||||||
import org.teavm.dependency.DependencyInfo;
|
import org.teavm.dependency.DependencyInfo;
|
||||||
import org.teavm.diagnostics.ProblemProvider;
|
import org.teavm.diagnostics.ProblemProvider;
|
||||||
import org.teavm.javascript.RenderingContext;
|
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.parsing.ClasspathClassHolderSource;
|
||||||
import org.teavm.tooling.sources.SourceFileProvider;
|
import org.teavm.tooling.sources.SourceFileProvider;
|
||||||
import org.teavm.tooling.sources.SourceFilesCopier;
|
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;
|
import org.teavm.vm.spi.AbstractRendererListener;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class TeaVMTool implements BaseTeaVMTool {
|
public class TeaVMTool implements BaseTeaVMTool {
|
||||||
private File targetDirectory = new File(".");
|
private File targetDirectory = new File(".");
|
||||||
|
private TeaVMTargetType targetType = TeaVMTargetType.JAVASCRIPT;
|
||||||
private String targetFileName = "classes.js";
|
private String targetFileName = "classes.js";
|
||||||
private boolean minifying = true;
|
private boolean minifying = true;
|
||||||
private String mainClass;
|
private String mainClass;
|
||||||
private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE;
|
private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE;
|
||||||
private Properties properties = new Properties();
|
private Properties properties = new Properties();
|
||||||
private boolean mainPageIncluded;
|
private boolean mainPageIncluded;
|
||||||
private boolean bytecodeLogging;
|
|
||||||
private boolean debugInformationGenerated;
|
private boolean debugInformationGenerated;
|
||||||
private boolean sourceMapsFileGenerated;
|
private boolean sourceMapsFileGenerated;
|
||||||
private boolean sourceFilesCopied;
|
private boolean sourceFilesCopied;
|
||||||
|
@ -66,6 +93,8 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
private TeaVMProgressListener progressListener;
|
private TeaVMProgressListener progressListener;
|
||||||
private TeaVM vm;
|
private TeaVM vm;
|
||||||
private List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
private List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
||||||
|
private DebugInformationBuilder debugEmitter;
|
||||||
|
private JavaScriptTarget javaScriptTarget;
|
||||||
|
|
||||||
public File getTargetDirectory() {
|
public File getTargetDirectory() {
|
||||||
return targetDirectory;
|
return targetDirectory;
|
||||||
|
@ -126,14 +155,6 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
this.mainPageIncluded = mainPageIncluded;
|
this.mainPageIncluded = mainPageIncluded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBytecodeLogging() {
|
|
||||||
return bytecodeLogging;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBytecodeLogging(boolean bytecodeLogging) {
|
|
||||||
this.bytecodeLogging = bytecodeLogging;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDebugInformationGenerated() {
|
public boolean isDebugInformationGenerated() {
|
||||||
return debugInformationGenerated;
|
return debugInformationGenerated;
|
||||||
}
|
}
|
||||||
|
@ -262,11 +283,34 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
sourceFileProviders.add(sourceFileProvider);
|
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 {
|
public void generate() throws TeaVMToolException {
|
||||||
try {
|
try {
|
||||||
cancelled = false;
|
cancelled = false;
|
||||||
log.info("Building JavaScript file");
|
log.info("Building JavaScript file");
|
||||||
TeaVMBuilder vmBuilder = new TeaVMBuilder();
|
TeaVMBuilder vmBuilder = new TeaVMBuilder(prepareTarget());
|
||||||
if (incremental) {
|
if (incremental) {
|
||||||
cacheDirectory.mkdirs();
|
cacheDirectory.mkdirs();
|
||||||
symbolTable = new FileSymbolTable(new File(cacheDirectory, "symbols"));
|
symbolTable = new FileSymbolTable(new File(cacheDirectory, "symbols"));
|
||||||
|
@ -276,7 +320,10 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
cachedClassSource = new DiskCachedClassHolderSource(cacheDirectory, symbolTable, fileTable,
|
cachedClassSource = new DiskCachedClassHolderSource(cacheDirectory, symbolTable, fileTable,
|
||||||
classSource, innerClassSource);
|
classSource, innerClassSource);
|
||||||
programCache = new DiskProgramCache(cacheDirectory, symbolTable, fileTable, innerClassSource);
|
programCache = new DiskProgramCache(cacheDirectory, symbolTable, fileTable, innerClassSource);
|
||||||
astCache = new DiskRegularMethodNodeCache(cacheDirectory, symbolTable, fileTable, innerClassSource);
|
|
||||||
|
if (targetType == TeaVMTargetType.JAVASCRIPT) {
|
||||||
|
astCache = new DiskRegularMethodNodeCache(cacheDirectory, symbolTable, fileTable, innerClassSource);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
symbolTable.update();
|
symbolTable.update();
|
||||||
fileTable.update();
|
fileTable.update();
|
||||||
|
@ -292,17 +339,11 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
if (progressListener != null) {
|
if (progressListener != null) {
|
||||||
vm.setProgressListener(progressListener);
|
vm.setProgressListener(progressListener);
|
||||||
}
|
}
|
||||||
vm.setMinifying(minifying);
|
|
||||||
vm.setBytecodeLogging(bytecodeLogging);
|
|
||||||
vm.setProperties(properties);
|
vm.setProperties(properties);
|
||||||
DebugInformationBuilder debugEmitter = debugInformationGenerated || sourceMapsFileGenerated
|
vm.setProgramCache(programCache);
|
||||||
? new DebugInformationBuilder() : null;
|
|
||||||
vm.setDebugEmitter(debugEmitter);
|
|
||||||
vm.setIncremental(incremental);
|
vm.setIncremental(incremental);
|
||||||
if (incremental) {
|
|
||||||
vm.setAstCache(astCache);
|
|
||||||
vm.setProgramCache(programCache);
|
|
||||||
}
|
|
||||||
vm.installPlugins();
|
vm.installPlugins();
|
||||||
for (ClassHolderTransformer transformer : transformers) {
|
for (ClassHolderTransformer transformer : transformers) {
|
||||||
vm.add(transformer);
|
vm.add(transformer);
|
||||||
|
@ -336,82 +377,96 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targetDirectory.mkdirs();
|
targetDirectory.mkdirs();
|
||||||
try (Writer writer = new OutputStreamWriter(new BufferedOutputStream(
|
try (OutputStream output = new BufferedOutputStream(
|
||||||
new FileOutputStream(new File(targetDirectory, targetFileName)), 65536), "UTF-8")) {
|
new FileOutputStream(new File(targetDirectory, targetFileName)), 65536)) {
|
||||||
|
Writer writer = new OutputStreamWriter(output, "UTF-8");
|
||||||
if (runtime == RuntimeCopyOperation.MERGED) {
|
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()) {
|
if (vm.wasCancelled()) {
|
||||||
log.info("Build cancelled");
|
log.info("Build cancelled");
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mainClass != null) {
|
|
||||||
writer.append("main = $rt_mainStarter(main);\n");
|
|
||||||
}
|
|
||||||
ProblemProvider problemProvider = vm.getProblemProvider();
|
ProblemProvider problemProvider = vm.getProblemProvider();
|
||||||
if (problemProvider.getProblems().isEmpty()) {
|
if (problemProvider.getProblems().isEmpty()) {
|
||||||
log.info("JavaScript file successfully built");
|
log.info("Output file successfully built");
|
||||||
} else if (problemProvider.getSevereProblems().isEmpty()) {
|
} else if (problemProvider.getSevereProblems().isEmpty()) {
|
||||||
log.info("JavaScript file built with warnings");
|
log.info("Output file built with warnings");
|
||||||
TeaVMProblemRenderer.describeProblems(vm, log);
|
TeaVMProblemRenderer.describeProblems(vm, log);
|
||||||
} else {
|
} else {
|
||||||
log.info("JavaScript file built with errors");
|
log.info("Output file built with errors");
|
||||||
TeaVMProblemRenderer.describeProblems(vm, log);
|
TeaVMProblemRenderer.describeProblems(vm, log);
|
||||||
}
|
}
|
||||||
if (debugInformationGenerated) {
|
|
||||||
assert debugEmitter != null;
|
if (targetType == TeaVMTargetType.JAVASCRIPT) {
|
||||||
DebugInformation debugInfo = debugEmitter.getDebugInformation();
|
additionalJavaScriptOutput(writer);
|
||||||
try (OutputStream debugInfoOut = new FileOutputStream(new File(targetDirectory,
|
|
||||||
targetFileName + ".teavmdbg"))) {
|
|
||||||
debugInfo.write(debugInfoOut);
|
|
||||||
}
|
|
||||||
log.info("Debug information successfully written");
|
|
||||||
}
|
|
||||||
if (sourceMapsFileGenerated) {
|
|
||||||
assert debugEmitter != null;
|
|
||||||
DebugInformation debugInfo = debugEmitter.getDebugInformation();
|
|
||||||
String sourceMapsFileName = targetFileName + ".map";
|
|
||||||
writer.append("\n//# sourceMappingURL=").append(sourceMapsFileName);
|
|
||||||
try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(
|
|
||||||
new File(targetDirectory, sourceMapsFileName)), "UTF-8")) {
|
|
||||||
debugInfo.writeAsSourceMaps(sourceMapsOut, "src", targetFileName);
|
|
||||||
}
|
|
||||||
log.info("Source maps successfully written");
|
|
||||||
}
|
|
||||||
if (sourceFilesCopied) {
|
|
||||||
copySourceFiles();
|
|
||||||
log.info("Source files successfully written");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (incremental) {
|
if (incremental) {
|
||||||
programCache.flush();
|
programCache.flush();
|
||||||
astCache.flush();
|
if (astCache != null) {
|
||||||
|
astCache.flush();
|
||||||
|
}
|
||||||
cachedClassSource.flush();
|
cachedClassSource.flush();
|
||||||
symbolTable.flush();
|
symbolTable.flush();
|
||||||
fileTable.flush();
|
fileTable.flush();
|
||||||
log.info("Cache updated");
|
log.info("Cache updated");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (runtime == RuntimeCopyOperation.SEPARATE) {
|
|
||||||
resourceToFile("org/teavm/javascript/runtime.js", "runtime.js");
|
|
||||||
}
|
|
||||||
if (mainPageIncluded) {
|
|
||||||
String text;
|
|
||||||
try (Reader reader = new InputStreamReader(classLoader.getResourceAsStream(
|
|
||||||
"org/teavm/tooling/main.html"), "UTF-8")) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TeaVMToolException("IO error occured", 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debugInformationGenerated) {
|
||||||
|
assert debugEmitter != null;
|
||||||
|
DebugInformation debugInfo = debugEmitter.getDebugInformation();
|
||||||
|
try (OutputStream debugInfoOut = new FileOutputStream(new File(targetDirectory,
|
||||||
|
targetFileName + ".teavmdbg"))) {
|
||||||
|
debugInfo.write(debugInfoOut);
|
||||||
|
}
|
||||||
|
log.info("Debug information successfully written");
|
||||||
|
}
|
||||||
|
if (sourceMapsFileGenerated) {
|
||||||
|
assert debugEmitter != null;
|
||||||
|
DebugInformation debugInfo = debugEmitter.getDebugInformation();
|
||||||
|
String sourceMapsFileName = targetFileName + ".map";
|
||||||
|
writer.append("\n//# sourceMappingURL=").append(sourceMapsFileName);
|
||||||
|
try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(
|
||||||
|
new File(targetDirectory, sourceMapsFileName)), "UTF-8")) {
|
||||||
|
debugInfo.writeAsSourceMaps(sourceMapsOut, "src", targetFileName);
|
||||||
|
}
|
||||||
|
log.info("Source maps successfully written");
|
||||||
|
}
|
||||||
|
if (sourceFilesCopied) {
|
||||||
|
copySourceFiles();
|
||||||
|
log.info("Source files successfully written");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runtime == RuntimeCopyOperation.SEPARATE) {
|
||||||
|
resourceToFile("org/teavm/javascript/runtime.js", "runtime.js");
|
||||||
|
}
|
||||||
|
if (mainPageIncluded) {
|
||||||
|
String text;
|
||||||
|
try (Reader reader = new InputStreamReader(classLoader.getResourceAsStream(
|
||||||
|
"org/teavm/tooling/main.html"), "UTF-8")) {
|
||||||
|
text = IOUtils.toString(reader).replace("${classes.js}", targetFileName);
|
||||||
|
}
|
||||||
|
File mainPageFile = new File(targetDirectory, "main.html");
|
||||||
|
try (Writer mainPageWriter = new OutputStreamWriter(new FileOutputStream(mainPageFile), "UTF-8")) {
|
||||||
|
mainPageWriter.append(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void copySourceFiles() {
|
private void copySourceFiles() {
|
||||||
if (vm.getWrittenClasses() == null) {
|
if (vm.getWrittenClasses() == null) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<property key="Bundle-Description" value="TeaVM API that helps to create tooling" />
|
<property key="Bundle-Description" value="TeaVM API that helps to create tooling" />
|
||||||
<property key="Export-Package" value="org.teavm.*" />
|
<property key="Export-Package" value="org.teavm.*" />
|
||||||
<property key="Bundle-Name" value="TeaVM tooling core" />
|
<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>
|
</additionalProperties>
|
||||||
<additionalJARContents />
|
<additionalJARContents />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -20,8 +20,6 @@ import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
@ -49,6 +47,7 @@ import org.junit.runners.model.InitializationError;
|
||||||
import org.teavm.callgraph.CallGraph;
|
import org.teavm.callgraph.CallGraph;
|
||||||
import org.teavm.diagnostics.DefaultProblemTextConsumer;
|
import org.teavm.diagnostics.DefaultProblemTextConsumer;
|
||||||
import org.teavm.diagnostics.Problem;
|
import org.teavm.diagnostics.Problem;
|
||||||
|
import org.teavm.javascript.target.JavaScriptTarget;
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.ClassHolder;
|
||||||
import org.teavm.model.ClassHolderSource;
|
import org.teavm.model.ClassHolderSource;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
|
@ -345,12 +344,13 @@ public class TeaVMTestRunner extends Runner {
|
||||||
MethodHolder methodHolder = classHolder.getMethod(getDescriptor(method));
|
MethodHolder methodHolder = classHolder.getMethod(getDescriptor(method));
|
||||||
Class<?> runnerType = testAdapter.getRunner(methodHolder);
|
Class<?> runnerType = testAdapter.getRunner(methodHolder);
|
||||||
|
|
||||||
TeaVM vm = new TeaVMBuilder()
|
JavaScriptTarget jsTarget = new JavaScriptTarget();
|
||||||
|
jsTarget.setMinifying(false);
|
||||||
|
TeaVM vm = new TeaVMBuilder(jsTarget)
|
||||||
.setClassLoader(classLoader)
|
.setClassLoader(classLoader)
|
||||||
.setClassSource(classSource)
|
.setClassSource(classSource)
|
||||||
.build();
|
.build();
|
||||||
vm.setIncremental(false);
|
vm.setIncremental(false);
|
||||||
vm.setMinifying(false);
|
|
||||||
vm.installPlugins();
|
vm.installPlugins();
|
||||||
|
|
||||||
new TestExceptionPlugin().install(vm);
|
new TestExceptionPlugin().install(vm);
|
||||||
|
@ -360,7 +360,7 @@ public class TeaVMTestRunner extends Runner {
|
||||||
applyProperties(method.getDeclaringClass(), properties);
|
applyProperties(method.getDeclaringClass(), properties);
|
||||||
vm.setProperties(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",
|
MethodReference exceptionMsg = new MethodReference(ExceptionHelper.class, "showException",
|
||||||
Throwable.class, String.class);
|
Throwable.class, String.class);
|
||||||
vm.entryPoint("runTest", new MethodReference(TestEntryPoint.class, "run", void.class)).async();
|
vm.entryPoint("runTest", new MethodReference(TestEntryPoint.class, "run", void.class)).async();
|
||||||
|
|
|
@ -55,9 +55,6 @@ public class BuildJavascriptMojo extends AbstractJavascriptMojo {
|
||||||
@Parameter
|
@Parameter
|
||||||
private boolean mainPageIncluded;
|
private boolean mainPageIncluded;
|
||||||
|
|
||||||
@Parameter
|
|
||||||
private boolean bytecodeLogging;
|
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private ClassAlias[] classAliases;
|
private ClassAlias[] classAliases;
|
||||||
|
|
||||||
|
@ -86,7 +83,6 @@ public class BuildJavascriptMojo extends AbstractJavascriptMojo {
|
||||||
setupTool(tool);
|
setupTool(tool);
|
||||||
tool.setLog(new MavenTeaVMToolLog(log));
|
tool.setLog(new MavenTeaVMToolLog(log));
|
||||||
try {
|
try {
|
||||||
tool.setBytecodeLogging(bytecodeLogging);
|
|
||||||
tool.setMainClass(mainClass);
|
tool.setMainClass(mainClass);
|
||||||
tool.setMainPageIncluded(mainPageIncluded);
|
tool.setMainPageIncluded(mainPageIncluded);
|
||||||
tool.setRuntime(runtime);
|
tool.setRuntime(runtime);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user