Iterable<OutputLanguage> outputLanguages,
Predicate<FileRef> allowedOutputPredicate) {
Set<CompilationUnit> extractMessagesFrom = Sets.newHashSet();
List<CompilationTask> sourceNotChanged = Lists.newArrayList();
for (CompilationUnit cUnit : getCompilationUnits()) {
FileRef sourceFileRef = cUnit.getSourceFileRef();
SourcePosition sourcePosition = new SourcePosition(sourceFileRef);
for (OutputLanguage language : outputLanguages) {
String suffix = language.getSuffix(compilationVersion);
FileRef outputFileRef = sourceFileRef.removeExtension().addSuffix(suffix);
if (allowedOutputPredicate.apply(outputFileRef)) {
extractMessagesFrom.add(cUnit);
CompilationTask task =
new CompilationTask(cUnit, codeGeneratorFactory, language,
outputFileRef);
// if the output file does not exist (last modified = 0) or if the source has been
// modified since the last time that the output has been generated, or if the source has
// changed, then we need to recompile the target
if (outputFileRef.getLastModified() < sourceFileRef.getLastModified()
|| manager.sourceChanged(task)) {
task.execute(alertSink, alertPolicy);
} else {
alertSink.add(new ProgressAlert(sourcePosition, "Skipped (source unchanged)"));
sourceNotChanged.add(task);
}
} else {
alertSink.add(new ProgressAlert(sourcePosition, "Skipped (output supressed)"));
}
}
}
// For each task we didn't execute, check to see if any of the interfaces
// it depends on have changed (which could happen as a result of
// recompiling one of the things it depends on).
// TODO(laurence): see whether it's possible to combine these two loops by
// having usedInterfacesChanged not change its value.
for (CompilationTask task : sourceNotChanged) {
if (manager.usedInterfacesChanged(task)) {
FileRef sourceFileRef = task.getCompilationUnit().getSourceFileRef();
SourcePosition sourcePosition = new SourcePosition(sourceFileRef);
alertSink.add(new ProgressAlert(sourcePosition, "Reconsidered; callees have changed"));
task.execute(alertSink, alertPolicy);
}
}