Skip to content

Commit

Permalink
AggressiveCompile: CompileListener (for generated and deleted files)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfatin authored and retronym committed Oct 19, 2013
1 parent f5ca955 commit c334865
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 15 deletions.
5 changes: 3 additions & 2 deletions compile/inc/src/main/scala/sbt/inc/Compile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ object IncrementalCompile
previous: Analysis,
forEntry: File => Option[Analysis],
output: Output, log: Logger,
options: IncOptions): (Boolean, Analysis) =
options: IncOptions,
deletionListener: Option[File => Unit] = None): (Boolean, Analysis) =
{
val current = Stamps.initial(Stamp.exists, Stamp.hash, Stamp.lastModified)
val internalMap = (f: File) => previous.relations.produced(f).headOption
val externalAPI = getExternalAPI(entry, forEntry)
try {
Incremental.compile(sources, entry, previous, current, forEntry, doCompile(compile, internalMap, externalAPI, current, output, options), log, options)
Incremental.compile(sources, entry, previous, current, forEntry, doCompile(compile, internalMap, externalAPI, current, output, options), log, options, deletionListener)
} catch {
case e: xsbti.CompileCancelled =>
log.info("Compilation has been cancelled")
Expand Down
21 changes: 13 additions & 8 deletions compile/inc/src/main/scala/sbt/inc/Incremental.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ object Incremental
forEntry: File => Option[Analysis],
doCompile: (Set[File], DependencyChanges) => Analysis,
log: Logger,
options: IncOptions)(implicit equivS: Equiv[Stamp]): (Boolean, Analysis) =
options: IncOptions,
deletionListener: Option[File => Unit] = None)(implicit equivS: Equiv[Stamp]): (Boolean, Analysis) =
{
val initialChanges = changedInitial(entry, sources, previous, current, forEntry, options, log)
val binaryChanges = new DependencyChanges {
Expand All @@ -30,7 +31,7 @@ object Incremental
val initialInv = invalidateInitial(previous.relations, initialChanges, log)
log.debug("All initially invalidated sources: " + initialInv + "\n")
val analysis = manageClassfiles(options) { classfileManager =>
cycle(initialInv, sources, binaryChanges, previous, doCompile, classfileManager, 1, log, options)
cycle(initialInv, sources, binaryChanges, previous, doCompile, classfileManager, 1, log, options, deletionListener)
}
(!initialInv.isEmpty, analysis)
}
Expand Down Expand Up @@ -59,15 +60,16 @@ object Incremental
// TODO: the Analysis for the last successful compilation should get returned + Boolean indicating success
// TODO: full external name changes, scopeInvalidations
@tailrec def cycle(invalidatedRaw: Set[File], allSources: Set[File], binaryChanges: DependencyChanges, previous: Analysis,
doCompile: (Set[File], DependencyChanges) => Analysis, classfileManager: ClassfileManager, cycleNum: Int, log: Logger, options: IncOptions): Analysis =
doCompile: (Set[File], DependencyChanges) => Analysis, classfileManager: ClassfileManager, cycleNum: Int, log: Logger, options: IncOptions,
deletionListener: Option[File => Unit]): Analysis =
if(invalidatedRaw.isEmpty)
previous
else
{
def debug(s: => String) = if (incDebug(options)) log.debug(s) else ()
val withPackageObjects = invalidatedRaw ++ invalidatedPackageObjects(invalidatedRaw, previous.relations)
val invalidated = expand(withPackageObjects, allSources, log, options)
val pruned = prune(invalidated, previous, classfileManager)
val pruned = prune(invalidated, previous, classfileManager, deletionListener)
debug("********* Pruned: \n" + pruned.relations + "\n*********")

val fresh = doCompile(invalidated, binaryChanges)
Expand All @@ -80,7 +82,7 @@ object Incremental
debug("\nChanges:\n" + incChanges)
val transitiveStep = options.transitiveStep
val incInv = invalidateIncremental(merged.relations, incChanges, invalidated, cycleNum >= transitiveStep, log)
cycle(incInv, allSources, emptyChanges, merged, doCompile, classfileManager, cycleNum+1, log, options)
cycle(incInv, allSources, emptyChanges, merged, doCompile, classfileManager, cycleNum+1, log, options, deletionListener)
}
private[this] def emptyChanges: DependencyChanges = new DependencyChanges {
val modifiedBinaries = new Array[File](0)
Expand Down Expand Up @@ -286,12 +288,15 @@ object Incremental
newInv ++ initialDependsOnNew
}

def prune(invalidatedSrcs: Set[File], previous: Analysis): Analysis =
prune(invalidatedSrcs, previous, ClassfileManager.deleteImmediately())
def prune(invalidatedSrcs: Set[File], previous: Analysis, deletionListener: Option[File => Unit]): Analysis =
prune(invalidatedSrcs, previous, ClassfileManager.deleteImmediately(), deletionListener)

def prune(invalidatedSrcs: Set[File], previous: Analysis, classfileManager: ClassfileManager): Analysis =
def prune(invalidatedSrcs: Set[File], previous: Analysis, classfileManager: ClassfileManager, deletionListener: Option[File => Unit]): Analysis =
{
val filesToDelete = invalidatedSrcs.flatMap(previous.relations.products)
classfileManager.delete( invalidatedSrcs.flatMap(previous.relations.products) )
deletionListener.foreach(listener => filesToDelete.foreach(listener(_)))

previous -- invalidatedSrcs
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import inc._

import xsbti.{ Reporter, AnalysisCallback }
import xsbti.api.Source
import xsbti.compile.{CompileOrder, DependencyChanges, GlobalsCache, Output, SingleOutput, MultipleOutput, CompileProgress}
import xsbti.compile.{CompileOrder, DependencyChanges, GlobalsCache, Output, SingleOutput, MultipleOutput, CompileProgress, ExtendedCompileProgress}
import CompileOrder.{JavaThenScala, Mixed, ScalaThenJava}

final class CompileConfiguration(val sources: Seq[File], val classpath: Seq[File],
Expand Down Expand Up @@ -86,7 +86,11 @@ class AggressiveCompile(cacheFile: File)
val searchClasspath = explicitBootClasspath(options.options) ++ cArgsOpt.map(it => withBootclasspath(it, absClasspath)).getOrElse(absClasspath)
val entry = Locate.entry(searchClasspath, definesClass)

val compile0 = (include: Set[File], changes: DependencyChanges, callback: AnalysisCallback) => {
val compile0 = (include: Set[File], changes: DependencyChanges, externalCallback: AnalysisCallback) => {
val callback = progress match {
case Some(ext: ExtendedCompileProgress) => new AnalysisCallbackAdapter(ext, externalCallback)
case _ => externalCallback
}
val outputDirs = outputDirectories(output)
outputDirs foreach (IO.createDirectory)
val incSrc = sources.filter(include)
Expand Down Expand Up @@ -147,12 +151,17 @@ class AggressiveCompile(cacheFile: File)
if(order == JavaThenScala) { compileJava(); compileScala() } else { compileScala(); compileJava() }
}

val deletionListener = (file: File) => config.progress.foreach {
case ext: ExtendedCompileProgress => ext.deleted(file)
case _ =>
}

val sourcesSet = sources.toSet
val analysis = previousSetup match {
case Some(previous) if equiv.equiv(previous, currentSetup) => previousAnalysis
case _ => Incremental.prune(sourcesSet, previousAnalysis)
case _ => Incremental.prune(sourcesSet, previousAnalysis, Some(deletionListener))
}
IncrementalCompile(sourcesSet, entry, compile0, analysis, getAnalysis, output, log, incOptions)
IncrementalCompile(sourcesSet, entry, compile0, analysis, getAnalysis, output, log, incOptions, Some(deletionListener))
}
private[this] def outputDirectories(output: Output): Seq[File] = output match {
case single: SingleOutput => List(single.outputDirectory)
Expand Down
34 changes: 34 additions & 0 deletions compile/src/main/scala/sbt/compiler/AnalysisCallbackAdapter.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package sbt.compiler

import xsbti.{Severity, Position, AnalysisCallback}
import xsbti.compile.ExtendedCompileProgress
import java.io.File
import xsbti.api.SourceAPI

class AnalysisCallbackAdapter(progress: ExtendedCompileProgress, delegate: AnalysisCallback) extends xsbti.AnalysisCallback{

def beginSource(source: File) =
delegate.beginSource(source)

def problem(what: String, pos: Position, msg: String, severity: Severity, reported: Boolean) =
delegate.problem(what, pos, msg, severity, reported)

def api(sourceFile: File, source: SourceAPI) =
delegate.api(sourceFile, source)

def endSource(sourcePath: File) =
delegate.endSource(sourcePath)

def generatedClass(source: File, module: File, name: String) = {
// NON BOILERPLATE
progress.generated(source, module, name)

delegate.generatedClass(source, module, name)
}

def binaryDependency(binary: File, name: String, source: File, publicInherited: Boolean) =
delegate.binaryDependency(binary, name, source, publicInherited)

def sourceDependency(dependsOn: File, source: File, publicInherited: Boolean) =
delegate.sourceDependency(dependsOn, source, publicInherited)
}
2 changes: 1 addition & 1 deletion interface/src/main/java/xsbti/compile/CompileProgress.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ public interface CompileProgress {
void startUnit(String phase, String unitPath);

boolean advance(int current, int total);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package xsbti.compile;

import java.io.File;

public interface ExtendedCompileProgress extends CompileProgress {
void generated(File source, File module, String name);

void deleted(File module);
}

0 comments on commit c334865

Please sign in to comment.