mirror of https://github.com/sbt/sbt.git
Properly apply transformations to dynamic tasks.
That is, implement Initialize[Task[T]].flatten correctly. This requires preserving the transformations applied in a scope so that they can be applied to an Initialize value after static settings have been evaluated.
This commit is contained in:
parent
0a642f2283
commit
b453af7c45
|
|
@ -32,10 +32,10 @@ object FullInstance extends Instance.Composed[Initialize, Task](InitializeInstan
|
|||
def flatten[T](in: Initialize[Task[Initialize[Task[T]]]]): Initialize[Task[T]] =
|
||||
{
|
||||
import Scoped._
|
||||
(in,settingsData) apply{
|
||||
(a: Task[Initialize[Task[T]]], data: Task[SS]) =>
|
||||
(in,settingsData, Def.capturedTransformations) apply{
|
||||
(a: Task[Initialize[Task[T]]], data: Task[SS], f) =>
|
||||
import TaskExtra.multT2Task
|
||||
(a, data) flatMap { case (a,d) => a evaluate d }
|
||||
(a, data) flatMap { case (a,d) => f(a) evaluate d }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ abstract class EvaluateSettings[Scope]
|
|||
case a: Apply[k,T] => new MixedNode[k,T]( a.alist.transform[Initialize, INode](a.inputs, transform), a.f, a.alist)
|
||||
case b: Bind[s,T] => new BindNode[s,T]( transform(b.in), x => transform(b.f(x)))
|
||||
case v: Value[T] => constant(v.value)
|
||||
case t: TransformCapture => constant(() => t.f)
|
||||
case o: Optional[s,T] => o.a match {
|
||||
case None => constant( () => o.f(None) )
|
||||
case Some(i) => single[s,T](transform(i), x => o.f(Some(x)))
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@ trait Init[Scope]
|
|||
type ScopeLocal = ScopedKey[_] => Seq[Setting[_]]
|
||||
type MapConstant = ScopedKey ~> Option
|
||||
|
||||
/** The result of this initialization is the composition of applied transformations.
|
||||
* This can be useful when dealing with dynamic Initialize values. */
|
||||
lazy val capturedTransformations: Initialize[Initialize ~> Initialize] = new TransformCapture(idK[Initialize])
|
||||
def setting[T](key: ScopedKey[T], init: Initialize[T], pos: SourcePosition = NoPosition): Setting[T] = new Setting[T](key, init, pos)
|
||||
def valueStrict[T](value: T): Initialize[T] = pure(() => value)
|
||||
def value[T](value: => T): Initialize[T] = pure(value _)
|
||||
|
|
@ -264,6 +267,14 @@ trait Init[Scope]
|
|||
override def toString = "setting(" + key + ") at " + pos
|
||||
}
|
||||
|
||||
private[this] def handleUndefined[T](vr: ValidatedInit[T]): Initialize[T] = vr match {
|
||||
case Left(undefs) => throw new RuntimeUndefined(undefs)
|
||||
case Right(x) => x
|
||||
}
|
||||
|
||||
private[this] lazy val getValidated =
|
||||
new (ValidatedInit ~> Initialize) { def apply[T](v: ValidatedInit[T]) = handleUndefined[T](v) }
|
||||
|
||||
// mainly for reducing generated class count
|
||||
private[this] def validateReferencedT(g: ValidateRef) =
|
||||
new (Initialize ~> ValidatedInit) { def apply[T](i: Initialize[T]) = i validateReferenced g }
|
||||
|
|
@ -302,6 +313,15 @@ trait Init[Scope]
|
|||
trait KeyedInitialize[T] extends Keyed[T, T] {
|
||||
final val transform = idFun[T]
|
||||
}
|
||||
private[sbt] final class TransformCapture(val f: Initialize ~> Initialize) extends Initialize[Initialize ~> Initialize]
|
||||
{
|
||||
def dependencies = Nil
|
||||
def apply[Z](g2: (Initialize ~> Initialize) => Z): Initialize[Z] = map(this)(g2)
|
||||
def evaluate(ss: Settings[Scope]): Initialize ~> Initialize = f
|
||||
def mapReferenced(g: MapScoped) = new TransformCapture(mapReferencedT(g) ∙ f)
|
||||
def mapConstant(g: MapConstant) = new TransformCapture(mapConstantT(g) ∙ f)
|
||||
def validateReferenced(g: ValidateRef) = Right(new TransformCapture(getValidated ∙ validateReferencedT(g) ∙ f))
|
||||
}
|
||||
private[sbt] final class Bind[S,T](val f: S => Initialize[T], val in: Initialize[S]) extends Initialize[T]
|
||||
{
|
||||
def dependencies = in.dependencies
|
||||
|
|
@ -311,10 +331,6 @@ trait Init[Scope]
|
|||
def validateReferenced(g: ValidateRef) = (in validateReferenced g).right.map { validIn =>
|
||||
new Bind[S,T](s => handleUndefined( f(s) validateReferenced g), validIn)
|
||||
}
|
||||
def handleUndefined(vr: ValidatedInit[T]): Initialize[T] = vr match {
|
||||
case Left(undefs) => throw new RuntimeUndefined(undefs)
|
||||
case Right(x) => x
|
||||
}
|
||||
def mapConstant(g: MapConstant) = new Bind[S,T](s => f(s) mapConstant g, in mapConstant g)
|
||||
}
|
||||
private[sbt] final class Optional[S,T](val a: Option[Initialize[S]], val f: Option[S] => T) extends Initialize[T]
|
||||
|
|
|
|||
Loading…
Reference in New Issue