proper resolvedScoped implementation

This commit is contained in:
Mark Harrah 2011-07-19 21:29:05 -04:00
parent f8183cc6f2
commit bf8b577e4f
5 changed files with 104 additions and 9 deletions

View File

@ -278,7 +278,7 @@ object Defaults extends BuildCommon
case (s, frameworks, par, opts, loader, discovered, scoped, (tests, frameworkOptions)) =>
val filter = selectedFilter(tests)
val modifiedOpts = Tests.Filter(filter) +: Tests.Argument(frameworkOptions : _*) +: opts
Tests(frameworks, loader, discovered, modifiedOpts, par, noTestsMessage(ScopedKey(scoped.scope, testOnly.key)), s.log) map { results =>
Tests(frameworks, loader, discovered, modifiedOpts, par, noTestsMessage(scoped), s.log) map { results =>
Tests.showResults(s.log, results)
}
}

View File

@ -6,7 +6,7 @@ package sbt
import java.io.File
import Project.{ScopedKey, Setting}
import Keys.{streams, Streams, TaskStreams}
import Keys.{dummyState, dummyStreamsManager, parseResult, resolvedScoped, streamsManager, taskDefinitionKey}
import Keys.{dummyState, dummyStreamsManager, parseResult, streamsManager, taskDefinitionKey}
import Scope.{GlobalScope, ThisScope}
import scala.Console.{RED, RESET}
@ -131,8 +131,6 @@ object EvaluateTask
stream.open()
stream
})
else if(scoped.key == resolvedScoped.key)
Seq(resolvedScoped in scoped.scope :== scoped)
else if(scoped.key == parseResult.key)
Seq(parseResult in scoped.scope := error("Unsubstituted parse result for " + Project.display(scoped)) )
else

View File

@ -127,14 +127,12 @@ object Load
// additionally, set the task axis to the defining key if it is not set
def finalTransforms(ss: Seq[Setting[_]]): Seq[Setting[_]] =
{
import Keys.{parseResult, resolvedScoped}
def isSpecial(key: AttributeKey[_]) = key == streams.key || key == resolvedScoped.key || key == parseResult.key
def isSpecial(key: AttributeKey[_]) = key == streams.key || key == parseResult.key
def mapSpecial(to: ScopedKey[_]) = new (ScopedKey ~> ScopedKey){ def apply[T](key: ScopedKey[T]) =
if(isSpecial(key.key))
{
val replaced = Scope.replaceThis(to.scope)(key.scope)
val scope = if(key.key == resolvedScoped.key) replaced else Scope.fillTaskAxis(replaced, to.key)
ScopedKey(scope, key.key)
ScopedKey(Scope.fillTaskAxis(replaced, to.key), key.key)
}
else key
}
@ -143,7 +141,10 @@ object Load
case ik: InputTask[t] => ik.mapTask( tk => setDefinitionKey(tk, key) ).asInstanceOf[T]
case _ => value
}
ss.map(s => s mapReferenced mapSpecial(s.key) mapInit setDefining )
def setResolved(defining: ScopedKey[_]) = new (ScopedKey ~> Option) { def apply[T](key: ScopedKey[T]): Option[T] =
if(key.key == resolvedScoped.key) Some(defining.asInstanceOf[T]) else None
}
ss.map(s => s mapReferenced mapSpecial(s.key) mapInit setDefining mapConstant setResolved(s.key))
}
def setDefinitionKey[T](tk: Task[T], key: ScopedKey[_]): Task[T] =
if(isDummy(tk)) tk else Task(tk.info.set(Keys.taskDefinitionKey, key), tk.work)

View File

@ -0,0 +1,75 @@
package sbt
import Types._
final case class ReducedH[K[_], HL <: HList, HLk <: HList](keys: KList[K, HLk], expand: HLk => HL)
{
def prepend[T](key: K[T])(g: K ~> Option) =
g(key) match
{
case None => ReducedH[K, T :+: HL, T :+: HLk]( KCons(key, keys), { case v :+: hli => HCons(v, expand(hli)) })
case Some(v) => ReducedH[K, T :+: HL, HLk](keys, hli => HCons(v, expand(hli)))
}
def combine[T](f: (KList[K, HLk], HLk => HL) => T): T = f(keys, expand)
}
final case class ReducedK[K[_], M[_], HL <: HList, HLk <: HList](keys: KList[(K M)#l, HLk], expand: KList[M, HLk] => KList[M, HL])
{
def prepend[T](key: K[M[T]])(g: (K M)#l ~> (Option M)#l): ReducedK[K, M, T :+: HL, _ <: HList] =
g(key) match
{
case None => ReducedK[K, M, T :+: HL, T :+: HLk]( KCons[T, HLk, (K M)#l](key, keys), { case KCons(v, hli) => KCons(v, expand(hli)) })
case Some(v) => ReducedK[K, M, T :+: HL, HLk](keys, hli => KCons(v, expand(hli)) )
}
def combine[T](f: (KList[(K M)#l, HLk], KList[M, HLk] => KList[M, HL]) => T): T = f(keys, expand)
}
final case class ReducedSeq[K[_], T](keys: Seq[K[T]], expand: Seq[T] => Seq[T])
{
def prepend(key: K[T])(g: K ~> Option) =
g(key) match
{
case None => ReducedSeq[K, T](key +: keys, { case Seq(x, xs @ _*) => x +: expand(xs) })
case Some(v) => ReducedSeq[K, T](keys, xs => v +: expand(xs))
}
}
object Reduced
{
def reduceK[HL <: HList, K[_], M[_]](keys: KList[(K M)#l, HL], g: (K M)#l ~> (Option M)#l): ReducedK[K, M, HL, _ <: HList] =
{
type RedK[HL <: HList] = ReducedK[K, M, HL, _ <: HList]
keys.foldr[RedK,(K M)#l] { new KFold[(K M)#l, RedK] {
def knil = emptyK
def kcons[H,T<:HList](h: K[M[H]], acc: RedK[T]): RedK[H :+: T] =
acc.prepend(h)(g)
}}
}
def reduceH[HL <: HList, K[_]](keys: KList[K, HL], g: K ~> Option): ReducedH[K, HL, _ <: HList] =
{
type RedH[HL <: HList] = ReducedH[K, HL, _ <: HList]
keys.foldr { new KFold[K, RedH] {
def knil = emptyH
def kcons[H,T<:HList](h: K[H], acc: RedH[T]): RedH[H :+: T] =
acc.prepend(h)(g)
}}
}
def reduceSeq[K[_], T](keys: Seq[K[T]], g: K ~> Option): ReducedSeq[K, T] = (ReducedSeq[K, T](Nil, idFun) /: keys) { (red, key) => red.prepend(key)(g) }
def emptyH[K[_]] = ReducedH[K, HNil, HNil](KNil, idFun)
def emptyK[K[_], M[_]] = ReducedK[K, M, HNil, HNil](KNil, idFun)
}
/*
def mapConstant(inputs: Seq[ScopedKey[S]], g: ScopedKey ~> Option) =
split(Nil, inputs.head, inputs.tails, g) match
{
None => new Uniform(f, inputs)
Some((left, x, Nil)) => new Uniform(in => f(in :+ x), left)
Some((Nil, x, right)) => new Uniform(in => f(x +: in), right)
Some((left, x, right)) => new Joined(uniformID(left), mapConstant(right), (l,r) => (l ++ (x +: r)) )
}
def split[S, M[_]](acc: List[M[S]], head: M[S], tail: List[M[S]], f: M ~> Option): Option[(Seq[M[S]], S, Seq[M[S]])] =
(f(head), tail) match
{
case (None, Nil) => None
case (None, x :: xs) => split( head :: acc, x, xs, f)
case (Some(v), ts) => Some( (acc.reverse, v, ts) )
}
*/

View File

@ -50,6 +50,7 @@ trait Init[Scope]
type CompiledMap = Map[ScopedKey[_], Compiled]
type MapScoped = ScopedKey ~> ScopedKey
type ScopeLocal = ScopedKey[_] => Seq[Setting[_]]
type MapConstant = ScopedKey ~> Option
def setting[T](key: ScopedKey[T], init: Initialize[T]): Setting[T] = new Setting[T](key, init)
def value[T](value: => T): Initialize[T] = new Value(value _)
@ -161,6 +162,7 @@ trait Init[Scope]
def mapReferenced(g: MapScoped): Initialize[T]
def zip[S](o: Initialize[S]): Initialize[(T,S)] = zipWith(o)((x,y) => (x,y))
def zipWith[S,U](o: Initialize[S])(f: (T,S) => U): Initialize[U] = new Joined[T,S,U](this, o, f)
def mapConstant(g: MapConstant): Initialize[T]
def get(map: Settings[Scope]): T
}
object Initialize
@ -190,6 +192,7 @@ trait Init[Scope]
def mapReferenced(g: MapScoped): Setting[T] = new Setting(key, init mapReferenced g)
def mapKey(g: MapScoped): Setting[T] = new Setting(g(key), init)
def mapInit(f: (ScopedKey[T], T) => T): Setting[T] = new Setting(key, init.map(t => f(key,t)))
def mapConstant(g: MapConstant): Setting[T] = new Setting(key, init mapConstant g)
override def toString = "setting(" + key + ")"
}
@ -199,6 +202,11 @@ trait Init[Scope]
def map[Z](g: T => Z): Initialize[Z] = new Optional[S,Z](a, g compose f)
def get(map: Settings[Scope]): T = f(a map asFunction(map))
def mapReferenced(g: MapScoped) = new Optional(mapKey(g), f)
def mapConstant(g: MapConstant): Initialize[T] =
(a flatMap g.fn) match {
case None => this
case s => new Value(() => f(s))
}
private[this] def mapKey(g: MapScoped) = try { a map g.fn } catch { case _: Uninitialized => None }
}
private[this] final class Joined[S,T,U](a: Initialize[S], b: Initialize[T], f: (S,T) => U) extends Initialize[U]
@ -206,6 +214,7 @@ trait Init[Scope]
def dependsOn = a.dependsOn ++ b.dependsOn
def mapReferenced(g: MapScoped) = new Joined(a mapReferenced g, b mapReferenced g, f)
def map[Z](g: U => Z) = new Joined[S,T,Z](a, b, (s,t) => g(f(s,t)))
def mapConstant(g: MapConstant) = new Joined[S,T,U](a mapConstant g, b mapConstant g, f)
def get(map: Settings[Scope]): U = f(a get map, b get map)
}
private[this] final class Value[T](value: () => T) extends Initialize[T]
@ -213,6 +222,7 @@ trait Init[Scope]
def dependsOn = Nil
def mapReferenced(g: MapScoped) = this
def map[S](g: T => S) = new Value[S](() => g(value()))
def mapConstant(g: MapConstant) = this
def get(map: Settings[Scope]): T = value()
}
private[this] final class Apply[HL <: HList, T](val f: HL => T, val inputs: KList[ScopedKey, HL]) extends Initialize[T]
@ -220,6 +230,7 @@ trait Init[Scope]
def dependsOn = inputs.toList
def mapReferenced(g: MapScoped) = new Apply(f, inputs transform g)
def map[S](g: T => S) = new Apply(g compose f, inputs)
def mapConstant(g: MapConstant) = Reduced.reduceH(inputs, g).combine( (keys, expand) => new Apply(f compose expand, keys) )
def get(map: Settings[Scope]) = f(inputs down asTransform(map) )
}
private[this] final class KApply[HL <: HList, M[_], T](val f: KList[M, HL] => T, val inputs: KList[({type l[t] = ScopedKey[M[t]]})#l, HL]) extends Initialize[T]
@ -228,6 +239,11 @@ trait Init[Scope]
def mapReferenced(g: MapScoped) = new KApply[HL, M, T](f, inputs.transform[({type l[t] = ScopedKey[M[t]]})#l]( nestCon(g) ) )
def map[S](g: T => S) = new KApply[HL, M, S](g compose f, inputs)
def get(map: Settings[Scope]) = f(inputs.transform[M]( nestCon[ScopedKey, Id, M](asTransform(map)) ))
def mapConstant(g: MapConstant) =
{
def mk[HLk <: HList](keys: KList[(ScopedKey M)#l, HLk], expand: KList[M, HLk] => KList[M, HL]) = new KApply[HLk, M, T](f compose expand, keys)
Reduced.reduceK[HL, ScopedKey, M](inputs, nestCon(g)) combine mk
}
private[this] def unnest(l: List[ScopedKey[M[T]] forSome { type T }]): List[ScopedKey[_]] = l.asInstanceOf[List[ScopedKey[_]]]
}
private[this] final class Uniform[S, T](val f: Seq[S] => T, val inputs: Seq[ScopedKey[S]]) extends Initialize[T]
@ -235,6 +251,11 @@ trait Init[Scope]
def dependsOn = inputs
def mapReferenced(g: MapScoped) = new Uniform(f, inputs map g.fn[S])
def map[S](g: T => S) = new Uniform(g compose f, inputs)
def mapConstant(g: MapConstant) =
{
val red = Reduced.reduceSeq(inputs, g)
new Uniform(f compose red.expand, red.keys)
}
def get(map: Settings[Scope]) = f(inputs map asFunction(map))
}
private def remove[T](s: Seq[T], v: T) = s filterNot (_ == v)