mirror of https://github.com/sbt/sbt.git
inline tasks, for internal use later
This commit is contained in:
parent
5ff33fad3e
commit
4b724e1102
|
|
@ -120,17 +120,17 @@ object EvaluateTask
|
|||
try { f(str) } finally { str.close() }
|
||||
}
|
||||
|
||||
def getTask[T](structure: BuildStructure, taskKey: ScopedKey[Task[T]], state: State, streams: Streams, ref: ProjectRef): Option[(Task[T], Execute.NodeView[Task])] =
|
||||
def getTask[T](structure: BuildStructure, taskKey: ScopedKey[Task[T]], state: State, streams: Streams, ref: ProjectRef): Option[(Task[T], NodeView[Task])] =
|
||||
{
|
||||
val thisScope = Load.projectScope(ref)
|
||||
val resolvedScope = Scope.replaceThis(thisScope)( taskKey.scope )
|
||||
for( t <- structure.data.get(resolvedScope, taskKey.key)) yield
|
||||
(t, nodeView(state, streams, taskKey :: Nil))
|
||||
}
|
||||
def nodeView[HL <: HList](state: State, streams: Streams, roots: Seq[ScopedKey[_]], extraDummies: KList[Task, HL] = KNil, extraValues: HL = HNil): Execute.NodeView[Task] =
|
||||
def nodeView[HL <: HList](state: State, streams: Streams, roots: Seq[ScopedKey[_]], extraDummies: KList[Task, HL] = KNil, extraValues: HL = HNil): NodeView[Task] =
|
||||
Transform(dummyRoots :^: dummyStreamsManager :^: KCons(dummyState, extraDummies), roots :+: streams :+: HCons(state, extraValues))
|
||||
|
||||
def runTask[T](root: Task[T], state: State, streams: Streams, triggers: Triggers[Task], config: EvaluateConfig)(implicit taskToNode: Execute.NodeView[Task]): (State, Result[T]) =
|
||||
def runTask[T](root: Task[T], state: State, streams: Streams, triggers: Triggers[Task], config: EvaluateConfig)(implicit taskToNode: NodeView[Task]): (State, Result[T]) =
|
||||
{
|
||||
import ConcurrentRestrictions.{completionService, TagMap, Tag, tagged, tagsKey}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ object Execute
|
|||
{
|
||||
trait Part1of2K[M[_[_], _], A[_]] { type Apply[T] = M[A, T] }
|
||||
type NodeT[A[_]] = Part1of2K[Node, A]
|
||||
type NodeView[A[_]] = A ~> NodeT[A]#Apply
|
||||
|
||||
def idMap[A,B]: Map[A, B] = JavaConversions.asScalaMap(new java.util.IdentityHashMap[A,B])
|
||||
def pMap[A[_], B[_]]: PMap[A,B] = new DelegatingPMap[A, B](idMap)
|
||||
|
|
@ -27,6 +26,11 @@ object Execute
|
|||
sealed trait Completed {
|
||||
def process(): Unit
|
||||
}
|
||||
trait NodeView[A[_]]
|
||||
{
|
||||
def apply[T](a: A[T]): Node[A, T]
|
||||
def inline[T](a: A[T]): Option[() => T]
|
||||
}
|
||||
final class Triggers[A[_]](val runBefore: collection.Map[A[_], Seq[A[_]]], val injectFor: collection.Map[A[_], Seq[A[_]]], val onComplete: RMap[A,Result] => RMap[A,Result])
|
||||
|
||||
final class Execute[A[_] <: AnyRef](checkCycles: Boolean, triggers: Triggers[A])(implicit view: NodeView[A])
|
||||
|
|
@ -40,6 +44,13 @@ final class Execute[A[_] <: AnyRef](checkCycles: Boolean, triggers: Triggers[A])
|
|||
private[this] val viewCache = pMap[A, NodeT[A]#Apply]
|
||||
private[this] val results = pMap[A, Result]
|
||||
|
||||
private[this] val getResult: A ~> Result = new (A ~> Result) {
|
||||
def apply[T](a: A[T]): Result[T] = view.inline(a) match {
|
||||
case Some(v) => Value(v())
|
||||
case None => results(a)
|
||||
}
|
||||
}
|
||||
|
||||
private[this] type State = State.Value
|
||||
private[this] object State extends Enumeration {
|
||||
val Pending, Running, Calling, Done = Value
|
||||
|
|
@ -216,8 +227,8 @@ final class Execute[A[_] <: AnyRef](checkCycles: Boolean, triggers: Triggers[A])
|
|||
def submit[T]( node: A[T] )(implicit strategy: Strategy)
|
||||
{
|
||||
val v = viewCache(node)
|
||||
val rs = v.mixedIn transform results
|
||||
val ud = v.uniformIn.map(results.apply[v.Uniform])
|
||||
val rs = v.mixedIn transform getResult
|
||||
val ud = v.uniformIn.map(getResult.apply[v.Uniform])
|
||||
strategy.submit( node, () => work(node, v.work(rs, ud)) )
|
||||
}
|
||||
/** Evaluates the computation 'f' for 'node'.
|
||||
|
|
@ -243,7 +254,7 @@ final class Execute[A[_] <: AnyRef](checkCycles: Boolean, triggers: Triggers[A])
|
|||
def addCaller[T](caller: A[T], target: A[T]): Unit = callers.getOrUpdate(target, IDSet.create[A[T]]) += caller
|
||||
|
||||
def dependencies(node: A[_]): Iterable[A[_]] = dependencies(viewCache(node))
|
||||
def dependencies(v: Node[A, _]): Iterable[A[_]] = v.uniformIn ++ v.mixedIn.toList
|
||||
def dependencies(v: Node[A, _]): Iterable[A[_]] = (v.uniformIn ++ v.mixedIn.toList).filter(dep => view.inline(dep).isEmpty)
|
||||
|
||||
def runBefore(node: A[_]): Seq[A[_]] = getSeq(triggers.runBefore, node)
|
||||
def triggeredBy(node: A[_]): Seq[A[_]] = getSeq(triggers.injectFor, node)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package sbt
|
|||
import Types._
|
||||
|
||||
/** Represents a task node in a format understood by the task evaluation engine Execute.
|
||||
* Heterogenous inputs (Mixed, tuple) and homogoneous (Uniform, sequence) are defined and consumed separately.
|
||||
* Heterogenous inputs (Mixed, tuple) and homogeneous (Uniform, sequence) are defined and consumed separately.
|
||||
*
|
||||
* @tparam A the task type
|
||||
* @tparam T the type computed by this node */
|
||||
|
|
|
|||
|
|
@ -12,8 +12,10 @@ package sbt
|
|||
|
||||
/** Defines a task compuation*/
|
||||
sealed trait Action[T]
|
||||
/** A direct computation of a value. */
|
||||
final case class Pure[T](f: () => T) extends Action[T]
|
||||
/** A direct computation of a value.
|
||||
* If `inline` is true, `f` will be evaluated on the scheduler thread without the overhead of normal scheduling when possible.
|
||||
* This is intended as an optimization for already evaluated values or very short computations. */
|
||||
final case class Pure[T](f: () => T, inline: Boolean) extends Action[T]
|
||||
/** Applies a function to the result of evaluating a heterogeneous list of other tasks.*/
|
||||
final case class Mapped[T, In <: HList](in: Tasks[In], f: Results[In] => T) extends Action[T]
|
||||
/** Computes another task to evaluate based on results from evaluating other tasks.*/
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import Execute._
|
|||
|
||||
object Transform
|
||||
{
|
||||
def fromDummy[T](original: Task[T])(action: => T): Task[T] = Task(original.info, Pure(action _))
|
||||
def fromDummy[T](original: Task[T])(action: => T): Task[T] = Task(original.info, Pure(action _, false))
|
||||
def fromDummyStrict[T](original: Task[T], value: T): Task[T] = fromDummy(original)( value)
|
||||
|
||||
implicit def to_~>| [K[_], V[_]](map: RMap[K,V]) : K ~>| V = new (K ~>| V) { def apply[T](k: K[T]): Option[V[T]] = map.get(k) }
|
||||
|
|
@ -39,17 +39,21 @@ object Transform
|
|||
def apply[HL <: HList, Key](dummies: KList[Task, HL], injected: HL) =
|
||||
{
|
||||
import System._
|
||||
taskToNode ∙ getOrId(dummyMap(dummies)(injected))
|
||||
taskToNode( getOrId(dummyMap(dummies)(injected)) )
|
||||
}
|
||||
|
||||
def taskToNode = new (Task ~> NodeT[Task]#Apply) {
|
||||
def apply[T](t: Task[T]): Node[Task, T] = t.work match {
|
||||
case Pure(eval) => toNode(KNil)( _ => Right(eval()) )
|
||||
def taskToNode(pre: Task ~> Task): NodeView[Task] = new NodeView[Task] {
|
||||
def apply[T](t: Task[T]): Node[Task, T] = pre(t).work match {
|
||||
case Pure(eval, _) => toNode(KNil)( _ => Right(eval()) )
|
||||
case Mapped(in, f) => toNode(in)( right ∙ f )
|
||||
case FlatMapped(in, f) => toNode(in)( left ∙ f )
|
||||
case DependsOn(in, deps) => toNode(KList.fromList(deps))( ((_:Any) => Left(in)) ∙ allM )
|
||||
case Join(in, f) => uniform(in)(f)
|
||||
}
|
||||
def inline[T](t: Task[T]) = t.work match {
|
||||
case Pure(eval, true) => Some(eval)
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
def uniform[T, D](tasks: Seq[Task[D]])(f: Seq[Result[D]] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,8 @@ trait TaskExtra
|
|||
final implicit def actionToTask[T](a: Action[T]): Task[T] = Task(Info(), a)
|
||||
|
||||
final def task[T](f: => T): Task[T] = toTask(f _)
|
||||
final implicit def toTask[T](f: () => T): Task[T] = new Pure(f)
|
||||
final implicit def toTask[T](f: () => T): Task[T] = new Pure(f, false)
|
||||
final def inlineTask[T](value: T): Task[T] = new Pure(() => value, true)
|
||||
|
||||
final implicit def upcastTask[A >: B, B](t: Task[B]): Task[A] = t map { x => x : B }
|
||||
final implicit def toTasks[S](in: Seq[() => S]): Seq[Task[S]] = in.map(toTask)
|
||||
|
|
|
|||
Loading…
Reference in New Issue