diff --git a/cache/Cache.scala b/cache/Cache.scala index 011d35211..2f35d2c96 100644 --- a/cache/Cache.scala +++ b/cache/Cache.scala @@ -23,18 +23,23 @@ object Cache extends BasicCacheImplicits with SBinaryFormats with HListCacheImpl def wrapOutputCache[O,DO](implicit convert: O => DO, reverse: DO => O, base: OutputCache[DO]): OutputCache[O] = new WrappedOutputCache[O,DO](convert, reverse, base) - /* Note: Task[O] { type Input = I } is written out because ITask[I,O] did not work (type could not be inferred properly) with a task - * with an HList input.*/ - def apply[I,O](task: Task[O] { type Input = I }, file: File)(implicit cache: Cache[I,O]): Task[O] { type Input = I } = - task match { case m: M[I,O,_] => - new M[I,O,Result[O]](None)(m.dependencies)(m.extract)(computeWithCache(m, cache, file)) - } - private def computeWithCache[I,O](m: M[I,O,_], cache: Cache[I,O], file: File)(in: I): Result[O] = - cache(file)(in) match - { - case Left(value) => Value(value) - case Right(store) => m.map { out => store(out); out } - } + def apply[I,O](file: File)(f: I => Task[O])(implicit cache: Cache[I,O]): I => Task[O] = + in => + cache(file)(in) match + { + case Left(value) => Task(value) + case Right(store) => f(in) map { out => store(out); out } + } + def cached[I,O](file: File)(f: I => O)(implicit cache: Cache[I,O]): I => O = + in => + cache(file)(in) match + { + case Left(value) => value + case Right(store) => + val out = f(in) + store(out) + out + } } trait BasicCacheImplicits extends NotNull { diff --git a/cache/HListCache.scala b/cache/HListCache.scala index eb3affd13..90f00f47d 100644 --- a/cache/HListCache.scala +++ b/cache/HListCache.scala @@ -1,18 +1,18 @@ package xsbt import java.io.{InputStream,OutputStream} -import metascala.HLists.{HCons,HList,HNil} +import HLists._ class HNilInputCache extends NoInputCache[HNil] class HConsInputCache[H,T <: HList](val headCache: InputCache[H], val tailCache: InputCache[T]) extends InputCache[HCons[H,T]] { def uptodate(in: HCons[H,T])(cacheStream: InputStream) = { - lazy val headResult = headCache.uptodate(in.head)(cacheStream) - lazy val tailResult = tailCache.uptodate(in.tail)(cacheStream) + val headResult = headCache.uptodate(in.head)(cacheStream) + val tailResult = tailCache.uptodate(in.tail)(cacheStream) new CacheResult { - lazy val uptodate = headResult.uptodate && tailResult.uptodate + val uptodate = headResult.uptodate && tailResult.uptodate def update(outputStream: OutputStream) = { headResult.update(outputStream) diff --git a/cache/src/test/scala/CacheTest.scala b/cache/src/test/scala/CacheTest.scala index f0cf919aa..7bba6ec79 100644 --- a/cache/src/test/scala/CacheTest.scala +++ b/cache/src/test/scala/CacheTest.scala @@ -4,19 +4,25 @@ import java.io.File object CacheTest// extends Properties("Cache test") { + val lengthCache = new File("/tmp/length-cache") + val cCache = new File("/tmp/c-cache") + import Task._ import Cache._ import FileInfo.hash._ - def checkFormattable(file: File) + def test { val createTask = Task { new File("test") } - val lengthTask = createTask map { f => println("File length: " + f.length); f.length } - val cached = Cache(lengthTask, new File("/tmp/length-cache")) - val cTask = (createTask :: cached :: TNil) map { case (file :: len :: HNil) => println("File: " + file + " length: " + len); len :: file :: HNil } - val cachedC = Cache(cTask, new File("/tmp/c-cache")) + val length = (f: File) => { println("File length: " + f.length); f.length } + val cachedLength = cached(lengthCache) ( length ) - try { TaskRunner(cachedC) } + val lengthTask = createTask map cachedLength + + val c = (file: File, len: Long) => { println("File: " + file + ", length: " + len); len :: file :: HNil } + val cTask = (createTask :: lengthTask :: TNil) map cached(cCache) { case (file :: len :: HNil) => c(file, len) } + + try { TaskRunner(cTask) } catch { case TasksFailed(failures) => failures.foreach(_.exception.printStackTrace) } } } \ No newline at end of file diff --git a/cache/tracking/Tracked.scala b/cache/tracking/Tracked.scala index 7eba581a0..72be00ac6 100644 --- a/cache/tracking/Tracked.scala +++ b/cache/tracking/Tracked.scala @@ -24,7 +24,7 @@ class Changed[O](val task: Task[O], val cacheFile: File)(implicit input: InputCa { val clean = Clean(cacheFile) def clear = Task.empty - def apply[O2](ifChanged: O => O2, ifUnchanged: O => O2): Task[O2] { type Input = O } = + def apply[O2](ifChanged: O => O2, ifUnchanged: O => O2): Task[O2] = task map { value => val cache = try { OpenResource.fileInputStream(cacheFile)(input.uptodate(value)) } diff --git a/util/collection/HLists.scala b/util/collection/HLists.scala index 4d4a00caa..f376ee4fd 100644 --- a/util/collection/HLists.scala +++ b/util/collection/HLists.scala @@ -1,15 +1,29 @@ package xsbt -import metascala.HLists.{HCons => metaHCons, HList => metaHList, HNil => metaHNil} +// stripped down version of http://trac.assembla.com/metascala/browser/src/metascala/HLists.scala +// Copyright (c) 2009, Jesper Nordenberg +// new BSD license, see licenses/MetaScala object HLists extends HLists -// add an extractor to metascala.HLists and define aliases to the HList classes in the xsbt namespace -trait HLists extends NotNull +trait HLists { object :: { def unapply[H,T<:HList](list: HCons[H,T]) = Some((list.head,list.tail)) } - final val HNil = metaHNil - final type ::[H, T <: HList] = metaHCons[H, T] - final type HNil = metaHNil - final type HList = metaHList - final type HCons[H, T <: HList] = metaHCons[H, T] + type ::[H, T <: HList] = HCons[H, T] +} + +object HNil extends HNil +sealed trait HList { + type Head + type Tail <: HList +} +sealed class HNil extends HList { + type Head = Nothing + type Tail = HNil + def ::[T](v : T) = HCons(v, this) +} + +final case class HCons[H, T <: HList](head : H, tail : T) extends HList { + type Head = H + type Tail = T + def ::[T](v : T) = HCons(v, this) } \ No newline at end of file diff --git a/util/collection/lib/metascala-0.1.jar b/util/collection/lib/metascala-0.1.jar deleted file mode 100644 index ea1d3a62b..000000000 Binary files a/util/collection/lib/metascala-0.1.jar and /dev/null differ