use of org.robovm.compiler.clazz.Clazz in project robovm by robovm.
the class ClassCompiler method mustCompile.
public boolean mustCompile(Clazz clazz) {
File oFile = config.getOFile(clazz);
if (!oFile.exists() || oFile.lastModified() < clazz.lastModified() || oFile.length() == 0) {
return true;
}
ClazzInfo ci = clazz.getClazzInfo();
if (ci == null) {
return true;
}
Set<Dependency> dependencies = ci.getAllDependencies();
for (Dependency dep : dependencies) {
Clazz depClazz = config.getClazzes().load(dep.getClassName());
if (depClazz == null) {
if (dep.getPath() != null) {
// depClazz was available the last time clazz was compiled but is now gone
return true;
}
} else {
if (dep.getPath() == null) {
// depClazz was not available the last time clazz was compiled but is now available
return true;
}
if (!dep.getPath().equals(depClazz.getPath().getFile().getAbsolutePath())) {
// depClazz was located in another place the last time clazz was built
return true;
}
if (depClazz.isInBootClasspath() != dep.isInBootClasspath()) {
// depClazz has moved to/from the bootclasspath since the last time clazz was built
return true;
}
if (depClazz.lastModified() > oFile.lastModified()) {
// depClazz has been changed since the last time clazz was built
return true;
}
}
}
// and the dependencies regenerated.
return dependencies.isEmpty();
}
use of org.robovm.compiler.clazz.Clazz in project robovm by robovm.
the class AppCompiler method compile.
public Set<Clazz> compile(Set<Clazz> rootClasses, boolean compileDependencies, final ClassCompilerListener listener) throws IOException {
config.getLogger().info("Compiling classes using %d threads", config.getThreads());
final Executor executor = (config.getThreads() <= 1) ? SAME_THREAD_EXECUTOR : new ThreadPoolExecutor(config.getThreads() - 1, config.getThreads() - 1, 0L, TimeUnit.MILLISECONDS, // determined by trial and error.
new ArrayBlockingQueue<Runnable>((config.getThreads() - 1) * 20));
class HandleFailureListener implements ClassCompilerListener {
volatile Throwable t;
@Override
public void success(Clazz clazz) {
if (listener != null) {
listener.success(clazz);
}
}
@Override
public void failure(Clazz clazz, Throwable t) {
// Compilation failed. Save the error and stop the executor.
this.t = t;
if (executor instanceof ExecutorService) {
((ExecutorService) executor).shutdown();
}
if (listener != null) {
listener.failure(clazz, t);
}
}
}
;
HandleFailureListener listenerWrapper = new HandleFailureListener();
DependencyGraph dependencyGraph = config.getDependencyGraph();
TreeSet<Clazz> compileQueue = new TreeSet<>(rootClasses);
long start = System.currentTimeMillis();
Set<Clazz> linkClasses = new HashSet<Clazz>();
int compiledCount = 0;
outer: while (!compileQueue.isEmpty() && !Thread.currentThread().isInterrupted()) {
while (!compileQueue.isEmpty() && !Thread.currentThread().isInterrupted()) {
Clazz clazz = compileQueue.pollFirst();
if (!linkClasses.contains(clazz)) {
if (compile(executor, listenerWrapper, clazz, compileQueue, linkClasses)) {
compiledCount++;
if (listenerWrapper.t != null) {
// We have a failed compilation. Stop compiling.
break outer;
}
}
dependencyGraph.add(clazz, rootClasses.contains(clazz));
linkClasses.add(clazz);
if (compileDependencies) {
addMetaInfImplementations(config.getClazzes(), clazz, linkClasses, compileQueue);
}
}
}
if (compileDependencies) {
for (String className : dependencyGraph.findReachableClasses()) {
Clazz depClazz = config.getClazzes().load(className);
if (depClazz != null && !linkClasses.contains(depClazz)) {
compileQueue.add(depClazz);
}
}
}
}
// Shutdown the executor and wait for running tasks to complete.
if (executor instanceof ExecutorService) {
ExecutorService executorService = (ExecutorService) executor;
executorService.shutdown();
try {
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {
}
}
if (listenerWrapper.t != null) {
// The compilation failed. Rethrow the exception in the callback.
if (listenerWrapper.t instanceof IOException) {
throw (IOException) listenerWrapper.t;
}
if (listenerWrapper.t instanceof RuntimeException) {
throw (RuntimeException) listenerWrapper.t;
}
if (listenerWrapper.t instanceof Error) {
throw (Error) listenerWrapper.t;
}
throw new CompilerException(listenerWrapper.t);
}
long duration = System.currentTimeMillis() - start;
config.getLogger().info("Compiled %d classes in %.2f seconds", compiledCount, duration / 1000.0);
return linkClasses;
}
use of org.robovm.compiler.clazz.Clazz in project robovm by robovm.
the class AppCompiler method addMetaInfImplementations.
static void addMetaInfImplementations(Clazzes clazzes, Clazz clazz, Set<Clazz> compiled, Set<Clazz> compileQueue) throws IOException {
String metaInfName = "META-INF/services/" + clazz.getClassName();
IOException throwLater = null;
for (InputStream is : clazzes.loadResources(metaInfName)) {
try (BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF8"))) {
for (; ; ) {
String line = r.readLine();
if (line == null) {
break;
}
if (line.startsWith("#")) {
continue;
}
String implClazzName = line.replace('.', '/');
Clazz implClazz = clazzes.load(implClazzName);
if (implClazz != null && !compiled.contains(implClazz)) {
compileQueue.add(implClazz);
}
}
} catch (IOException ex) {
throwLater = ex;
}
}
if (throwLater != null) {
throw throwLater;
}
}
Aggregations