mirror of https://github.com/sbt/sbt.git
API: base types with applied type parameters
Compile task: fix detection of classpath changes Aggressive compiler seems to work on scalaz now
This commit is contained in:
parent
5f9f3729d1
commit
af288bb199
|
|
@ -16,6 +16,22 @@ trait Tracked extends NotNull
|
||||||
/** Clears the cache. If also cleaning, 'clean' should be called first as it might require information from the cache.*/
|
/** Clears the cache. If also cleaning, 'clean' should be called first as it might require information from the cache.*/
|
||||||
def clear: Task[Unit]
|
def clear: Task[Unit]
|
||||||
}
|
}
|
||||||
|
class Timestamp(val cacheFile: File) extends Tracked
|
||||||
|
{
|
||||||
|
val clean = Clean(cacheFile)
|
||||||
|
def clear = Task.empty
|
||||||
|
def apply[T](f: Long => Task[T]): Task[T] =
|
||||||
|
{
|
||||||
|
val getTimestamp = Task { readTimestamp }
|
||||||
|
getTimestamp bind f map { result =>
|
||||||
|
FileUtilities.write(cacheFile, System.currentTimeMillis.toString)
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def readTimestamp: Long =
|
||||||
|
try { FileUtilities.read(cacheFile).toLong }
|
||||||
|
catch { case _: NumberFormatException | _: java.io.FileNotFoundException => 0 }
|
||||||
|
}
|
||||||
object Clean
|
object Clean
|
||||||
{
|
{
|
||||||
def apply(src: Task[Set[File]]): Task[Unit] = src map FileUtilities.delete
|
def apply(src: Task[Set[File]]): Task[Unit] = src map FileUtilities.delete
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,6 @@ private class SameAPI(a: Source, b: Source)
|
||||||
//println("Comparing \n\t" + show(a) + "\nagainst\n\t" + show(b))
|
//println("Comparing \n\t" + show(a) + "\nagainst\n\t" + show(b))
|
||||||
def sameDefs(a: List[Definition], b: List[Definition]): Boolean =
|
def sameDefs(a: List[Definition], b: List[Definition]): Boolean =
|
||||||
{
|
{
|
||||||
println("\t " + a.size + " to " + b.size + "")
|
|
||||||
a match
|
a match
|
||||||
{
|
{
|
||||||
case adef :: atail =>
|
case adef :: atail =>
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,13 @@ final class API(val global: Global, val callback: xsbti.AnalysisCallback) extend
|
||||||
{
|
{
|
||||||
val s = info.typeSymbol
|
val s = info.typeSymbol
|
||||||
val (declared, inherited) = info.members.partition(_.owner == s)
|
val (declared, inherited) = info.members.partition(_.owner == s)
|
||||||
structure(info.baseClasses.map(_.tpe), declared, inherited) // linearization instead of parents
|
// would be nice to know how to do this properly:
|
||||||
|
// baseClasses contains symbols in proper linearization order, but tpe doesn't have type parameters applied
|
||||||
|
// baseTypeSeq contains the types with parameters properly applied
|
||||||
|
val bases = info.baseClasses.tail
|
||||||
|
val bs = info.baseTypeSeq.toList.tail
|
||||||
|
val baseTypes = bases.map(base => bs.find(_.typeSymbol eq base).get)
|
||||||
|
structure(baseTypes, declared, inherited)
|
||||||
}
|
}
|
||||||
private def structure(parents: List[Type], declared: List[Symbol], inherited: List[Symbol]): xsbti.api.Structure =
|
private def structure(parents: List[Type], declared: List[Symbol], inherited: List[Symbol]): xsbti.api.Structure =
|
||||||
new xsbti.api.Structure(types(parents), processDefinitions(declared), Array())//processDefinitions(inherited))
|
new xsbti.api.Structure(types(parents), processDefinitions(declared), Array())//processDefinitions(inherited))
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ class AggressiveCompile(val cacheDirectory: File, val compilerTask: Task[Analyzi
|
||||||
def apply(sourceChanges: ChangeReport[File], classpathChanges: ChangeReport[File], outputDirectory: File, options: Seq[String]): Task[Set[File]] =
|
def apply(sourceChanges: ChangeReport[File], classpathChanges: ChangeReport[File], outputDirectory: File, options: Seq[String]): Task[Set[File]] =
|
||||||
compilerTask bind { compiler =>
|
compilerTask bind { compiler =>
|
||||||
tracking { tracker =>
|
tracking { tracker =>
|
||||||
|
timestamp { tstamp =>
|
||||||
Task {
|
Task {
|
||||||
log.info("Removed sources: \n\t" + sourceChanges.removed.mkString("\n\t"))
|
log.info("Removed sources: \n\t" + sourceChanges.removed.mkString("\n\t"))
|
||||||
log.info("Added sources: \n\t" + sourceChanges.added.mkString("\n\t"))
|
log.info("Added sources: \n\t" + sourceChanges.added.mkString("\n\t"))
|
||||||
|
|
@ -68,22 +69,29 @@ class AggressiveCompile(val cacheDirectory: File, val compilerTask: Task[Analyzi
|
||||||
val readTracker = tracker.read
|
val readTracker = tracker.read
|
||||||
// directories that are no longer on the classpath, not necessarily removed from the filesystem
|
// directories that are no longer on the classpath, not necessarily removed from the filesystem
|
||||||
val removedDirectories = classpathChanges.removed.filter(_.isDirectory)
|
val removedDirectories = classpathChanges.removed.filter(_.isDirectory)
|
||||||
|
log.info("Directories no longer on classpath:\n\t" + removedDirectories.mkString("\n\t"))
|
||||||
|
|
||||||
def uptodate(time: Long, files: Iterable[File]) = files.forall(_.lastModified <= time)
|
def uptodate(time: Long, files: Iterable[File]) = files.forall(_.lastModified < time)
|
||||||
def isOutofdate(file: File, related: => Iterable[File]) = !file.exists || !uptodate(file.lastModified, related)
|
def isOutofdate(file: File, related: => Iterable[File]) = !file.exists || !uptodate(file.lastModified, related)
|
||||||
|
def invalidatesUses(file: File) = !file.exists || file.lastModified > tstamp
|
||||||
def isProductOutofdate(product: File) = isOutofdate(product, readTracker.sources(product))
|
def isProductOutofdate(product: File) = isOutofdate(product, readTracker.sources(product))
|
||||||
def inRemovedDirectory(file: File) = removedDirectories.exists(dir => FileUtilities.relativize(dir, file).isDefined)
|
def inRemovedDirectory(file: File) = removedDirectories.exists(dir => FileUtilities.relativize(dir, file).isDefined)
|
||||||
def isUsedOutofdate(file: File) = classpathChanges.modified(file) || inRemovedDirectory(file) || isOutofdate(file, readTracker.usedBy(file))
|
def isUsedOutofdate(file: File) = classpathChanges.modified(file) || inRemovedDirectory(file) || invalidatesUses(file)
|
||||||
|
|
||||||
// these are products that no longer exist or are older than the sources that produced them
|
// these are products that no longer exist or are older than the sources that produced them
|
||||||
val outofdateProducts = readTracker.allProducts.filter(isProductOutofdate)
|
val outofdateProducts = readTracker.allProducts.filter(isProductOutofdate)
|
||||||
|
log.info("Out of date products:\n\t" + outofdateProducts.mkString("\n\t"))
|
||||||
// used classes and jars that a) no longer exist b) are no longer on the classpath or c) are newer than the sources that use them
|
// used classes and jars that a) no longer exist b) are no longer on the classpath or c) are newer than the sources that use them
|
||||||
val outofdateUses = readTracker.allUsed.filter(isUsedOutofdate)
|
val outofdateUses = readTracker.allUsed.filter(isUsedOutofdate)
|
||||||
|
log.info("Out of date binaries:\n\t" + outofdateUses.mkString("\n\t"))
|
||||||
|
|
||||||
val modifiedSources = sourceChanges.modified
|
val modifiedSources = sourceChanges.modified
|
||||||
val invalidatedByClasspath = outofdateUses.flatMap(readTracker.usedBy)
|
val invalidatedByClasspath = outofdateUses.flatMap(readTracker.usedBy)
|
||||||
|
log.info("Invalidated by classpath changes:\n\t" + invalidatedByClasspath.mkString("\n\t"))
|
||||||
val invalidatedByRemovedSrc = sourceChanges.removed.flatMap(readTracker.dependsOn)
|
val invalidatedByRemovedSrc = sourceChanges.removed.flatMap(readTracker.dependsOn)
|
||||||
|
log.info("Invalidated by removed sources:\n\t" + invalidatedByRemovedSrc.mkString("\n\t"))
|
||||||
val productsOutofdate = outofdateProducts.flatMap(readTracker.sources)
|
val productsOutofdate = outofdateProducts.flatMap(readTracker.sources)
|
||||||
|
log.info("Invalidated by out of date products:\n\t" + productsOutofdate.mkString("\n\t"))
|
||||||
|
|
||||||
val rawInvalidatedSources = modifiedSources ++ invalidatedByClasspath ++ invalidatedByRemovedSrc ++ productsOutofdate
|
val rawInvalidatedSources = modifiedSources ++ invalidatedByClasspath ++ invalidatedByRemovedSrc ++ productsOutofdate
|
||||||
val invalidatedSources = scc(readTracker, rawInvalidatedSources)
|
val invalidatedSources = scc(readTracker, rawInvalidatedSources)
|
||||||
|
|
@ -96,7 +104,7 @@ class AggressiveCompile(val cacheDirectory: File, val compilerTask: Task[Analyzi
|
||||||
tracker.pending(sources)
|
tracker.pending(sources)
|
||||||
FileUtilities.delete(invalidatedProducts)
|
FileUtilities.delete(invalidatedProducts)
|
||||||
|
|
||||||
log.info("Initially invalidated sources:\n\t" + sources.mkString("\n\t"))
|
log.info("All initially invalidated sources:\n\t" + sources.mkString("\n\t"))
|
||||||
if(!sources.isEmpty)
|
if(!sources.isEmpty)
|
||||||
{
|
{
|
||||||
val newAPIMap = doCompile(sources, classpath, outputDirectory, options, tracker, compiler, log)
|
val newAPIMap = doCompile(sources, classpath, outputDirectory, options, tracker, compiler, log)
|
||||||
|
|
@ -115,7 +123,7 @@ class AggressiveCompile(val cacheDirectory: File, val compilerTask: Task[Analyzi
|
||||||
}
|
}
|
||||||
Set() ++ tracker.read.allProducts
|
Set() ++ tracker.read.allProducts
|
||||||
}
|
}
|
||||||
}
|
}}
|
||||||
}
|
}
|
||||||
def products(tracker: ReadTracking[File], srcs: Set[File]): Set[File] = srcs.flatMap(tracker.products)
|
def products(tracker: ReadTracking[File], srcs: Set[File]): Set[File] = srcs.flatMap(tracker.products)
|
||||||
|
|
||||||
|
|
@ -129,7 +137,8 @@ class AggressiveCompile(val cacheDirectory: File, val compilerTask: Task[Analyzi
|
||||||
|
|
||||||
import sbinary.DefaultProtocol.FileFormat
|
import sbinary.DefaultProtocol.FileFormat
|
||||||
val tracking = new DependencyTracked(cacheDirectory, true, (files: File) => FileUtilities.delete(files))
|
val tracking = new DependencyTracked(cacheDirectory, true, (files: File) => FileUtilities.delete(files))
|
||||||
def tracked = Seq(tracking)
|
val timestamp = new Timestamp(new File(cacheDirectory,"timestamp"))
|
||||||
|
def tracked = Seq(tracking, timestamp)
|
||||||
|
|
||||||
def sameAPI[T](a: scala.collection.Map[T, Source], b: scala.collection.Map[T, Source], t: T): Boolean = sameAPI(a.get(t), b.get(t))
|
def sameAPI[T](a: scala.collection.Map[T, Source], b: scala.collection.Map[T, Source], t: T): Boolean = sameAPI(a.get(t), b.get(t))
|
||||||
def sameAPI(a: Option[Source], b: Option[Source]): Boolean =
|
def sameAPI(a: Option[Source], b: Option[Source]): Boolean =
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue