diff --git a/launch/src/test/scala/CacheTest.scala b/launch/src/test/scala/CacheTest.scala index ef76b6b44..4dd0ff3ab 100644 --- a/launch/src/test/scala/CacheTest.scala +++ b/launch/src/test/scala/CacheTest.scala @@ -5,7 +5,7 @@ import Prop._ object CacheTest extends Properties("Cache") { - implicit val functions: Arbitrary[Int => Int] = Arbitrary { Gen.elements(identity[Int], i => -i, i=>i/2, i => i+1) } + implicit val functions: Arbitrary[Int => Int] = Arbitrary { Gen.oneOf( Seq(identity[Int], i => -i, i=>i/2, i => i+1) ) } property("Cache") = Prop.forAll { (key: Int, keys: List[Int], map: Int => Int) => val cache = new Cache( (i: Int, _: Unit) => map(i) ) diff --git a/launch/src/test/scala/PreTest.scala b/launch/src/test/scala/PreTest.scala index 76d9beec8..6c2f17343 100644 --- a/launch/src/test/scala/PreTest.scala +++ b/launch/src/test/scala/PreTest.scala @@ -1,6 +1,7 @@ package xsbt.boot import java.io.File +import java.util.Arrays.equals import org.scalacheck._ object PreTest extends Properties("Pre") @@ -16,8 +17,8 @@ object PreTest extends Properties("Pre") property("require true") = Prop.forAll { (s: String) => require(true, s); true } property("error") = Prop.forAll( (s: String) => Prop.throws(error(s), classOf[BootException]) ) property("toBoolean") = Prop.forAll( (s: String) => trap(toBoolean(s)) == trap(java.lang.Boolean.parseBoolean(s)) ) - property("toArray") = Prop.forAll( (list: List[Int]) => list.toArray deepEquals toArray(list) ) - property("toArray") = Prop.forAll( (list: List[String]) => list.toArray deepEquals toArray(list) ) + property("toArray") = Prop.forAll( (list: List[Int]) => equals(list.toArray, toArray(list)) ) + property("toArray") = Prop.forAll( (list: List[String]) => equals(list.toArray, toArray(list)) ) property("concat") = Prop.forAll(genFiles, genFiles) { (a: Array[File], b: Array[File]) => (a ++ b) sameElements concat(a, b) } property("array") = Prop.forAll(genFiles) { (a: Array[File]) => array(a.toList : _*) sameElements Array(a: _*) } diff --git a/main/Aggregation.scala b/main/Aggregation.scala index 28812fc63..498135659 100644 --- a/main/Aggregation.scala +++ b/main/Aggregation.scala @@ -9,6 +9,7 @@ package sbt import java.net.URI import Parser._ import collection.mutable + import std.Transform.{DummyTaskMap, TaskAndValue} sealed trait Aggregation final object Aggregation @@ -27,9 +28,9 @@ final object Aggregation def applyTasks[T](s: State, structure: BuildStructure, ps: Values[Parser[Task[T]]], show: Boolean)(implicit display: Show[ScopedKey[_]]): Parser[() => State] = Command.applyEffect(seqParser(ps)) { ts => - runTasks(s, structure, ts, Dummies(KNil, HNil), show) + runTasks(s, structure, ts, DummyTaskMap(Nil), show) } - def runTasksWithResult[HL <: HList, T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: Dummies[HL], show: Boolean)(implicit display: Show[ScopedKey[_]]): (State, Result[Seq[KeyValue[T]]]) = + def runTasksWithResult[T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: DummyTaskMap, show: Boolean)(implicit display: Show[ScopedKey[_]]): (State, Result[Seq[KeyValue[T]]]) = { import EvaluateTask._ import std.TaskExtra._ @@ -41,7 +42,7 @@ final object Aggregation val start = System.currentTimeMillis val (newS, result) = withStreams(structure, s){ str => - val transform = nodeView(s, str, roots, extra.tasks, extra.values) + val transform = nodeView(s, str, roots, extra) runTask(toRun, s,str, structure.index.triggers, config)(transform) } val stop = System.currentTimeMillis @@ -54,7 +55,7 @@ final object Aggregation (newS, result) } - def runTasks[HL <: HList, T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: Dummies[HL], show: Boolean)(implicit display: Show[ScopedKey[_]]): State = { + def runTasks[HL <: HList, T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: DummyTaskMap, show: Boolean)(implicit display: Show[ScopedKey[_]]): State = { runTasksWithResult(s, structure, ts, extra, show)._1 } @@ -92,14 +93,13 @@ final object Aggregation DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM) } - final case class Dummies[HL <: HList](tasks: KList[Task,HL], values: HL) def applyDynamicTasks[I](s: State, structure: BuildStructure, inputs: Values[InputDynamic[I]], show: Boolean)(implicit display: Show[ScopedKey[_]]): Parser[() => State] = { val parsers = inputs.map { case KeyValue(k,t) => KeyValue(k, t parser s) } Command.applyEffect(seqParser(parsers)) { parseds => import EvaluateTask._ val inputMap = (Map.empty[AnyRef,Any] /: (inputs zip parseds)) { case (im, (id, v)) => im + ((id.value.defined, v.value)) } - val dummies = Dummies( InputTask.inputMap :^: KNil, inputMap :+: HNil) + val dummies = DummyTaskMap(new TaskAndValue(InputTask.inputMap, inputMap) :: Nil) val roots = inputs.map { case KeyValue(k,t) => KeyValue(k,t.task) } runTasks(s, structure, roots, dummies, show) } diff --git a/main/Defaults.scala b/main/Defaults.scala index 2da216e85..117f8da1d 100755 --- a/main/Defaults.scala +++ b/main/Defaults.scala @@ -428,7 +428,7 @@ object Defaults extends BuildCommon def packageSrcTask = packageSrcMappings private type Mappings = Initialize[Task[Seq[(File, String)]]] - def concatMappings(as: Mappings, bs: Mappings) = (as zipWith bs)( (a,b) => (a :^: b :^: KNil) map { case a :+: b :+: HNil => a ++ b } ) + def concatMappings(as: Mappings, bs: Mappings) = (as zipWith bs)( (a,b) => (a, b) map { case (a, b) => a ++ b } ) // drop base directories, since there are no valid mappings for these def sourceMappings = (unmanagedSources, unmanagedSourceDirectories, baseDirectory) map { (srcs, sdirs, base) => @@ -542,7 +542,7 @@ object Defaults extends BuildCommon val srcs = in.config.sources val hasScala = srcs.exists(_.name.endsWith(".scala")) val hasJava = srcs.exists(_.name.endsWith(".java")) - val cp = in.config.classpath.toList - in.config.classesDirectory + val cp = in.config.classpath.toList.filterNot(_ == in.config.classesDirectory) val label = nameForSrc(config.name) val (options, runDoc) = if(hasScala) @@ -741,7 +741,7 @@ object Classpaths lazy val defaultArtifactTasks: Seq[TaskKey[File]] = makePom +: defaultPackages def findClasspathConfig(map: Configuration => Configuration, thisConfig: Configuration, delegate: Task[Option[Configuration]], up: Task[UpdateReport]): Task[Configuration] = - (delegate :^: up :^: KNil) map { case delegated :+: report :+: HNil => + (delegate, up) map { case (delegated, report) => val defined = report.allConfigurations.toSet val search = map(thisConfig) +: (delegated.toList ++ Seq(Compile, Configurations.Default)) def notFound = error("Configuration to use for managed classpath must be explicitly defined when default configurations are not present.") @@ -950,7 +950,6 @@ object Classpaths def cachedUpdate(cacheFile: File, label: String, module: IvySbt#Module, config: UpdateConfiguration, scalaInstance: Option[ScalaInstance], skip: Boolean, force: Boolean, depsUpdated: Boolean, log: Logger): UpdateReport = { implicit val updateCache = updateIC - implicit val updateReport = updateReportFormat type In = IvyConfiguration :+: ModuleSettings :+: UpdateConfiguration :+: HNil def work = (_: In) match { case conf :+: settings :+: config :+: HNil => log.info("Updating " + label + "...") @@ -1314,14 +1313,14 @@ trait BuildExtra extends BuildCommon def fullRunInputTask(scoped: InputKey[Unit], config: Configuration, mainClass: String, baseArguments: String*): Setting[InputTask[Unit]] = scoped <<= inputTask { result => ( initScoped(scoped.scopedKey, runnerInit) zipWith (fullClasspath in config, streams, result).identityMap) { (rTask, t) => - (t :^: rTask :^: KNil) map { case (cp, s, args) :+: r :+: HNil => + (t, rTask) map { case ((cp, s, args), r) => toError(r.run(mainClass, data(cp), baseArguments ++ args, s.log)) } } } def fullRunTask(scoped: TaskKey[Unit], config: Configuration, mainClass: String, arguments: String*): Setting[Task[Unit]] = scoped <<= ( initScoped(scoped.scopedKey, runnerInit) zipWith (fullClasspath in config, streams).identityMap ) { case (rTask, t) => - (t :^: rTask :^: KNil) map { case (cp, s) :+: r :+: HNil => + (t, rTask) map { case ((cp, s), r) => toError(r.run(mainClass, data(cp), arguments, s.log)) } } diff --git a/main/EvaluateTask.scala b/main/EvaluateTask.scala index c11983de5..fd3dd4160 100644 --- a/main/EvaluateTask.scala +++ b/main/EvaluateTask.scala @@ -11,6 +11,7 @@ package sbt import Scope.{GlobalScope, ThisScope} import Types.const import scala.Console.RED + import std.Transform.{DummyTaskMap,TaskAndValue} final case class EvaluateConfig(cancelable: Boolean, restrictions: Seq[Tags.Rule], checkCycles: Boolean = false) final case class PluginData(dependencyClasspath: Seq[Attributed[File]], definitionClasspath: Seq[Attributed[File]], resolvers: Option[Seq[Resolver]], report: Option[UpdateReport]) @@ -136,8 +137,8 @@ object EvaluateTask 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): NodeView[Task] = - Transform(dummyRoots :^: dummyStreamsManager :^: KCons(dummyState, extraDummies), roots :+: streams :+: HCons(state, extraValues)) + def nodeView[HL <: HList](state: State, streams: Streams, roots: Seq[ScopedKey[_]], dummies: DummyTaskMap = DummyTaskMap(Nil)): NodeView[Task] = + Transform((dummyRoots, roots) :: (dummyStreamsManager, streams) :: (dummyState, state) :: dummies ) def runTask[T](root: Task[T], state: State, streams: Streams, triggers: Triggers[Task], config: EvaluateConfig)(implicit taskToNode: NodeView[Task]): (State, Result[T]) = { diff --git a/main/Extracted.scala b/main/Extracted.scala index a9462df18..d48627206 100644 --- a/main/Extracted.scala +++ b/main/Extracted.scala @@ -3,6 +3,7 @@ package sbt import Project._ import Scope.GlobalScope import Def.{ScopedKey, Setting} + import std.Transform.DummyTaskMap final case class Extracted(structure: BuildStructure, session: SessionSettings, currentRef: ProjectRef)(implicit val showKey: Show[ScopedKey[_]]) { @@ -30,7 +31,7 @@ final case class Extracted(structure: BuildStructure, session: SessionSettings, val rkey = resolve(key.scopedKey) val keys = Aggregation.aggregate(rkey, ScopeMask(), structure.extra) val tasks = Act.keyValues(structure)(keys) - Aggregation.runTasks(state, structure, tasks, Aggregation.Dummies(KNil, HNil), show = false )(showKey) + Aggregation.runTasks(state, structure, tasks, DummyTaskMap(Nil), show = false )(showKey) } private[this] def resolve[T](key: ScopedKey[T]): ScopedKey[T] = Project.mapScope(Scope.resolveScope(GlobalScope, currentRef.build, rootProject) )( key.scopedKey ) diff --git a/main/Output.scala b/main/Output.scala index 22b6c44aa..6a43b8645 100644 --- a/main/Output.scala +++ b/main/Output.scala @@ -44,7 +44,7 @@ object Output def lastLines(keys: Values[_], streams: Streams): Values[Seq[String]] = { - val outputs = keys map { case KeyValue(key, value) => KeyValue(key, lastLines(key, streams)) } + val outputs = keys map { (kv: KeyValue[_]) => KeyValue(kv.key, lastLines(kv.key, streams)) } outputs.filterNot(_.value.isEmpty) } def lastLines(key: ScopedKey[_], mgr: Streams): Seq[String] = mgr.use(key) { s => IO.readLines(s.readText( Project.fillTaskAxis(key) )) } diff --git a/main/Project.scala b/main/Project.scala index 68cb4df55..8ff6c0796 100755 --- a/main/Project.scala +++ b/main/Project.scala @@ -327,11 +327,6 @@ object Project extends ProjectExtra EvaluateTask(extracted.structure, taskKey, state, extracted.currentRef, config) } - /** Many methods were moved to Def in 0.13. This implicit makes those methods still available on Project for the transition. */ - @inline - @deprecated("Use Def directly", "0.13.0") - implicit def projectToDef(p: Project.type): Def.type = Def - implicit def projectToRef(p: Project): ProjectReference = LocalProject(p.id) final class RichTaskSessionVar[S](i: Initialize[Task[S]]) diff --git a/main/SettingGraph.scala b/main/SettingGraph.scala index 2fffb4e6b..aa8650cfd 100644 --- a/main/SettingGraph.scala +++ b/main/SettingGraph.scala @@ -24,7 +24,7 @@ object SettingGraph SettingGraph(display(scoped), definedIn, Project.scopedKeyData(structure, scope, key), key.description, basedir, - depends map { apply(structure, basedir, _, generation + 1) }) + depends map { (x: ScopedKey[_]) => apply(structure, basedir, x, generation + 1) }) } } diff --git a/main/settings/Structure.scala b/main/settings/Structure.scala index 8734ba47f..2b3bce010 100644 --- a/main/settings/Structure.scala +++ b/main/settings/Structure.scala @@ -76,7 +76,9 @@ object InputTask sealed trait Scoped { def scope: Scope; val key: AttributeKey[_] } /** A common type for SettingKey and TaskKey so that both can be used as inputs to tasks.*/ -sealed trait ScopedTaskable[T] extends Scoped +sealed trait ScopedTaskable[T] extends Scoped { + def toTask: Initialize[Task[T]] +} /** Identifies a setting. It consists of three parts: the scope, the name, and the type of a value associated with this key. * The scope is represented by a value of type Scope. @@ -85,6 +87,7 @@ sealed trait ScopedTaskable[T] extends Scoped sealed trait SettingKey[T] extends ScopedTaskable[T] with KeyedInitialize[T] with Scoped.ScopingSetting[SettingKey[T]] with Scoped.DefinableSetting[T] with Scoped.ListSetting[T, Id] { val key: AttributeKey[T] + def toTask: Initialize[Task[T]] = this apply inlineTask def scopedKey: ScopedKey[T] = ScopedKey(scope, key) def in(scope: Scope): SettingKey[T] = Scoped.scopedSetting(Scope.replaceThis(this.scope)(scope), this.key) @@ -98,10 +101,11 @@ sealed trait SettingKey[T] extends ScopedTaskable[T] with KeyedInitialize[T] wit sealed trait TaskKey[T] extends ScopedTaskable[T] with KeyedInitialize[Task[T]] with Scoped.ScopingSetting[TaskKey[T]] with Scoped.ListSetting[T, Task] with Scoped.DefinableTask[T] { val key: AttributeKey[Task[T]] + def toTask: Initialize[Task[T]] = this def scopedKey: ScopedKey[Task[T]] = ScopedKey(scope, key) def in(scope: Scope): TaskKey[T] = Scoped.scopedTask(Scope.replaceThis(this.scope)(scope), this.key) - protected[this] def make[S](other: Initialize[Task[S]])(f: (T, S) => T): Setting[Task[T]] = this <<= (this, other) { (a,b) => (a,b) map f } + protected[this] def make[S](other: Initialize[Task[S]])(f: (T, S) => T): Setting[Task[T]] = this <<= (this, other) { (a,b) => (a,b) map f.tupled } } /** Identifies an input task. An input task parses input and produces a task to run. @@ -189,7 +193,7 @@ object Scoped def ? : Initialize[Task[Option[S]]] = Def.optional(scopedKey) { case None => mktask { None }; case Some(t) => t map some.fn } def ??[T >: S](or: => T): Initialize[Task[T]] = Def.optional(scopedKey)( _ getOrElse mktask(or) ) - def or[T >: S](i: Initialize[Task[T]]): Initialize[Task[T]] = (this.? zipWith i)( (x,y) => (x :^: y :^: KNil) map hf2( _ getOrElse _ )) + def or[T >: S](i: Initialize[Task[T]]): Initialize[Task[T]] = (this.? zipWith i)( (x,y) => (x, y) map { case (a,b) => a getOrElse b}) } final class RichInitializeTask[S](i: Initialize[Task[S]]) extends RichInitTaskBase[S, Task] { @@ -248,87 +252,26 @@ object Scoped final class RichFileSetting(s: SettingKey[File]) extends RichFileBase { + @deprecated("Use a standard setting definition.", "0.13.0") def /(c: String): Initialize[File] = s { _ / c } protected[this] def map0(f: PathFinder => PathFinder) = s(file => finder(f)(file :: Nil)) } final class RichFilesSetting(s: SettingKey[Seq[File]]) extends RichFileBase { + @deprecated("Use a standard setting definition.", "0.13.0") def /(s: String): Initialize[Seq[File]] = map0 { _ / s } protected[this] def map0(f: PathFinder => PathFinder) = s(finder(f)) } sealed abstract class RichFileBase { + @deprecated("Use a standard setting definition.", "0.13.0") def *(filter: FileFilter): Initialize[Seq[File]] = map0 { _ * filter } + @deprecated("Use a standard setting definition.", "0.13.0") def **(filter: FileFilter): Initialize[Seq[File]] = map0 { _ ** filter } protected[this] def map0(f: PathFinder => PathFinder): Initialize[Seq[File]] protected[this] def finder(f: PathFinder => PathFinder): Seq[File] => Seq[File] = in => f(in).get } - - /* - * Reduced and combine provide support for mixed Setting/Task flatMap/map. - * The general idea is to take a KList of ScopedTaskables, which are either SettingKeys or TaskKeys, - * and uniformly provide multi-flatMap/map for constructing a new Task. - * For example: {{{ (SettingKeyA, TaskKeyB) flatMap { (a,b) => ... } }}} - */ - - trait Reduced[HLs <: HList, HLt <: HList, HLv <: HList] - { o => - def settings: KList[Initialize, HLs] // SS[A] :^: SS[Task[B]] :^: ... - def tasks(hls: HLs): KList[Task, HLt] // takes setting values from previous line to Task[B] :^: ... - def expand(hls: HLs, hlt: Results[HLt]): Results[HLv] // takes Result[B] :+: ... to Value[A] :+: Result[B] :+: ... - - def prependTask[H](key: Initialize[Task[H]]) = - new Reduced[Task[H] :+: HLs, H :+: HLt, H :+: HLv] - { - val settings = KCons(key, o.settings) - def tasks(hls: Task[H] :+: HLs) = KCons(hls.head, o.tasks(hls.tail)) - def expand(hls: Task[H] :+: HLs, hlt: Results[H :+: HLt]) = KCons(hlt.head, o.expand(hls.tail, hlt.tail) ) - } - - def prependSetting[H](key: Initialize[H]) = - new Reduced[H :+: HLs, HLt, H :+: HLv] - { - val settings = KCons(key, o.settings) - def tasks(hls: H :+: HLs) = o.tasks(hls.tail) - def expand(hls: H :+: HLs, hlt: Results[HLt]) = KCons(Value(hls.head), o.expand(hls.tail, hlt)) - } - def prependTaskable[H](key: ScopedTaskable[H]): Reduced[_,_,H :+: HLv] = - key match - { - case ss: SettingKey[H] => prependSetting(ss) - case st: TaskKey[H] => prependTask(scopedSetting(st.scope, st.key)) - } - - def combine[D[_],S](c: Combine[D], f: Results[HLv] => D[S]): Initialize[Task[S]] = - Def.app(settings)(hls => c(tasks(hls))(hlt => f(expand(hls, hlt))) ) - } - type RedHL[HL <: HList] = Reduced[_,_,HL] - def reduced[HL <: HList](settings: KList[ScopedTaskable, HL]): Reduced[_,_,HL] = - settings.foldr { new KFold[ScopedTaskable, RedHL] { - def knil = emptyReduced - def kcons[H,T<:HList](h: ScopedTaskable[H], acc: Reduced[_,_,T]): Reduced[_,_,H :+: T] = - acc prependTaskable h - }} - def emptyReduced: Reduced[HNil,HNil,HNil] = new Reduced[HNil,HNil,HNil] { - def settings = KNil - def tasks(h: HNil) = KNil - def expand(a: HNil, k: Results[HNil]) = KNil - } - trait Combine[D[_]] { - def apply[HL <: HList,S](tasks: KList[Task, HL])(f: Results[HL] => D[S]): Task[S] - } - object Combine - { - val mapR: Combine[Id] = new Combine[Id] { - def apply[HL <: HList,S](tasks: KList[Task, HL])(f: Results[HL] => S): Task[S] = - tasks mapR f - } - val flatMapR: Combine[Task] = new Combine[Task] { - def apply[HL <: HList,S](tasks: KList[Task, HL])(f: Results[HL] => Task[S]): Task[S] = - tasks flatMapR f - } - } // this is the least painful arrangement I came up with implicit def t2ToTable2[A,B](t2: (ScopedTaskable[A], ScopedTaskable[B]) ): RichTaskable2[A,B] = new RichTaskable2(t2) @@ -341,145 +284,133 @@ object Scoped implicit def t9ToTable9[A,B,C,D,E,F,G,H,I](t9: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I]) ): RichTaskable9[A,B,C,D,E,F,G,H,I] = new RichTaskable9(t9) implicit def t10ToTable10[A,B,C,D,E,F,G,H,I,J](t10: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J]) ): RichTaskable10[A,B,C,D,E,F,G,H,I,J] = new RichTaskable10(t10) implicit def t11ToTable11[A,B,C,D,E,F,G,H,I,J,K](t11: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K]) ): RichTaskable11[A,B,C,D,E,F,G,H,I,J,K] = new RichTaskable11(t11) - implicit def t12ToTable12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L]) ): RichTaskable12[A,B,C,D,E,F,G,H,I,J,K,L] = new RichTaskable12(t12) +/* implicit def t12ToTable12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L]) ): RichTaskable12[A,B,C,D,E,F,G,H,I,J,K,L] = new RichTaskable12(t12) implicit def t13ToTable13[A,B,C,D,E,F,G,H,I,J,K,L,N](t13: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N]) ): RichTaskable13[A,B,C,D,E,F,G,H,I,J,K,L,N] = new RichTaskable13(t13) implicit def t14ToTable14[A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N], ScopedTaskable[O]) ): RichTaskable14[A,B,C,D,E,F,G,H,I,J,K,L,N,O] = new RichTaskable14(t14) - implicit def t15ToTable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N], ScopedTaskable[O], ScopedTaskable[P]) ): RichTaskable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P] = new RichTaskable15(t15) + implicit def t15ToTable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N], ScopedTaskable[O], ScopedTaskable[P]) ): RichTaskable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P] = new RichTaskable15(t15)*/ - sealed abstract class RichTaskables[In <: HList](keys: KList[ScopedTaskable, In]) + sealed abstract class RichTaskables[K[L[x]]](final val keys: K[ScopedTaskable])(implicit a: AList[K]) { type App[T] = Initialize[Task[T]] type Fun[M[_],Ret] - protected def convertH[Ret](f: Fun[Id,Ret]): In => Ret - protected def convertK[M[_],Ret](f: Fun[M,Ret]): KList[M,In] => Ret - private[this] val red = reduced(keys) + protected def convert[M[_],Ret](f: Fun[M,Ret]): K[M] => Ret + private[this] val inputs: K[App] = a.transform(keys, new (ScopedTaskable ~> App) { def apply[T](in: ScopedTaskable[T]): App[T] = in.toTask }) + private[this] def onTasks[T](f: K[Task] => Task[T]): App[T] = Def.app[({ type l[L[x]] = K[ (L ∙ Task)#l] })#l,Task[T]](inputs)(f)(AList.asplit[K,Task](a)) - def flatMap[T](f: Fun[Id,Task[T]]): App[T] = red.combine(Combine.flatMapR, convertH(f) compose allM) - def flatMapR[T](f: Fun[Result,Task[T]]): App[T] = red.combine(Combine.flatMapR, convertK(f)) - def map[T](f: Fun[Id, T]): App[T] = red.combine[Id,T](Combine.mapR, convertH(f) compose allM) - def mapR[T](f: Fun[Result,T]): App[T] = red.combine[Id,T](Combine.mapR, convertK(f)) - def flatFailure[T](f: Seq[Incomplete] => Task[T]): App[T] = red.combine(Combine.flatMapR, f compose anyFailM) - def mapFailure[T](f: Seq[Incomplete] => T): App[T] = red.combine[Id,T](Combine.mapR, f compose anyFailM) + def flatMap[T](f: Fun[Id,Task[T]]): App[T] = onTasks(_.flatMap(convert(f))) + def flatMapR[T](f: Fun[Result,Task[T]]): App[T] = onTasks(_.flatMapR(convert(f))) + def map[T](f: Fun[Id, T]): App[T] = onTasks(_.mapR( convert(f) compose allM)) + def mapR[T](f: Fun[Result,T]): App[T] = onTasks(_.mapR(convert(f))) + def flatFailure[T](f: Seq[Incomplete] => Task[T]): App[T] = onTasks(_ flatFailure f) + def mapFailure[T](f: Seq[Incomplete] => T): App[T] = onTasks(_ mapFailure f) } - final class RichTaskable2[A,B](t2: (ScopedTaskable[A], ScopedTaskable[B])) extends RichTaskables(k2(t2)) + type :@:[H, T <: KList[ScopedTaskable]] = KCons[H, T, ScopedTaskable] + type ST[X] = ScopedTaskable[X] + final class RichTaskable2[A,B](t2: (ST[A], ST[B])) extends RichTaskables[ AList.T2K[A,B]#l ](t2)(AList.tuple2[A,B]) { type Fun[M[_],Ret] = (M[A],M[B]) => Ret def identityMap = map(mkTuple2) - protected def convertH[R](z: (A,B) => R) = hf2(z) - protected def convertK[M[_],R](f: (M[A],M[B]) => R) = { case a :^: b :^: KNil => f(a,b) } + protected def convert[M[_],R](f: (M[A],M[B]) => R) = f.tupled } - final class RichTaskable3[A,B,C](t3: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C])) extends RichTaskables(k3(t3)) + final class RichTaskable3[A,B,C](t3: (ST[A], ST[B], ST[C])) extends RichTaskables[ AList.T3K[A,B,C]#l](t3)(AList.tuple3[A,B,C]) { type Fun[M[_],Ret] = (M[A],M[B],M[C]) => Ret def identityMap = map(mkTuple3) - protected def convertH[R](z: Fun[Id,R]) = hf3(z) - protected def convertK[M[_],R](f: Fun[M,R]) = { case a :^: b :^: c :^: KNil => f(a,b,c) } + protected def convert[M[_],R](f: Fun[M,R]) = f.tupled } - final class RichTaskable4[A,B,C,D](t4: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D])) extends RichTaskables(k4(t4)) + final class RichTaskable4[A,B,C,D](t4: (ST[A], ST[B], ST[C], ST[D])) extends RichTaskables[ AList.T4K[A,B,C,D]#l](t4)(AList.tuple4[A,B,C,D]) { type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D]) => Ret def identityMap = map(mkTuple4) - protected def convertH[R](z: Fun[Id,R]) = hf4(z) - protected def convertK[M[_],R](f: Fun[M,R]) = { case a :^: b :^: c :^: d :^: KNil => f(a,b,c,d) } + protected def convert[M[_],R](f: Fun[M,R]) = f.tupled } - final class RichTaskable5[A,B,C,D,E](t5: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E])) extends RichTaskables(k5(t5)) + final class RichTaskable5[A,B,C,D,E](t5: (ST[A], ST[B], ST[C], ST[D], ST[E])) extends RichTaskables[AList.T5K[A,B,C,D,E]#l](t5)(AList.tuple5[A,B,C,D,E]) { type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D],M[E]) => Ret def identityMap = map(mkTuple5) - protected def convertH[R](z: Fun[Id,R]) = hf5(z) - protected def convertK[M[_],R](f: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: KNil => f(a,b,c,d,e) } + protected def convert[M[_],R](f: Fun[M,R]) = f.tupled } - final class RichTaskable6[A,B,C,D,E,F](t6: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F])) extends RichTaskables(k6(t6)) + final class RichTaskable6[A,B,C,D,E,F](t6: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F])) extends RichTaskables[AList.T6K[A,B,C,D,E,F]#l](t6)(AList.tuple6[A,B,C,D,E,F]) { type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D],M[E],M[F]) => Ret def identityMap = map(mkTuple6) - protected def convertH[R](z: Fun[Id,R]) = hf6(z) - protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: KNil => z(a,b,c,d,e,f) } + protected def convert[M[_],R](z: Fun[M,R]) = z.tupled } - final class RichTaskable7[A,B,C,D,E,F,G](t7: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G])) extends RichTaskables(k7(t7)) + final class RichTaskable7[A,B,C,D,E,F,G](t7: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G])) extends RichTaskables[AList.T7K[A,B,C,D,E,F,G]#l](t7)(AList.tuple7[A,B,C,D,E,F,G]) { type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D],M[E],M[F],M[G]) => Ret def identityMap = map(mkTuple7) - protected def convertH[R](z: Fun[Id,R]) = hf7(z) - protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: KNil => z(a,b,c,d,e,f,g) } + protected def convert[M[_],R](z: Fun[M,R]) = z.tupled } - final class RichTaskable8[A,B,C,D,E,F,G,H](t8: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H])) extends RichTaskables(k8(t8)) + final class RichTaskable8[A,B,C,D,E,F,G,H](t8: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H])) extends RichTaskables[AList.T8K[A,B,C,D,E,F,G,H]#l](t8)(AList.tuple8[A,B,C,D,E,F,G,H]) { type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D],M[E],M[F],M[G],M[H]) => Ret def identityMap = map(mkTuple8) - protected def convertH[R](z: Fun[Id,R]) = hf8(z) - protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: KNil => z(a,b,c,d,e,f,g,h) } + protected def convert[M[_],R](z: Fun[M,R]) = z.tupled } - final class RichTaskable9[A,B,C,D,E,F,G,H,I](t9: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I])) extends RichTaskables(k9(t9)) + final class RichTaskable9[A,B,C,D,E,F,G,H,I](t9: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I])) extends RichTaskables[AList.T9K[A,B,C,D,E,F,G,H,I]#l](t9)(AList.tuple9[A,B,C,D,E,F,G,H,I]) { type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D],M[E],M[F],M[G],M[H],M[I]) => Ret def identityMap = map(mkTuple9) - protected def convertH[R](z: Fun[Id,R]) = hf9(z) - protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: KNil => z(a,b,c,d,e,f,g,h,i) } + protected def convert[M[_],R](z: Fun[M,R]) = z.tupled } - final class RichTaskable10[A,B,C,D,E,F,G,H,I,J](t10: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J]))) extends RichTaskables(k10(t10)) + final class RichTaskable10[A,B,C,D,E,F,G,H,I,J](t10: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J]))) extends RichTaskables[AList.T10K[A,B,C,D,E,F,G,H,I,J]#l](t10)(AList.tuple10[A,B,C,D,E,F,G,H,I,J]) { type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J]) => Ret def identityMap = map(mkTuple10) - protected def convertH[R](z: Fun[Id,R]) = hf10(z) - protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: KNil => z(a,b,c,d,e,f,g,h,i,j) } + protected def convert[M[_],R](z: Fun[M,R]) = z.tupled } - final class RichTaskable11[A,B,C,D,E,F,G,H,I,J,K](t11: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K]))) extends RichTaskables(k11(t11)) + final class RichTaskable11[A,B,C,D,E,F,G,H,I,J,K](t11: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K]))) extends RichTaskables[AList.T11K[A,B,C,D,E,F,G,H,I,J,K]#l](t11)(AList.tuple11[A,B,C,D,E,F,G,H,I,J,K]) { type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K]) => Ret def identityMap = map(mkTuple11) - protected def convertH[R](z: Fun[Id,R]) = hf11(z) - protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: k :^: KNil => z(a,b,c,d,e,f,g,h,i,j,k) } + protected def convert[M[_],R](z: Fun[M,R]) = z.tupled } - final class RichTaskable12[A,B,C,D,E,F,G,H,I,J,K,L](t12: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L]))) extends RichTaskables(k12(t12)) +/* final class RichTaskable12[A,B,C,D,E,F,G,H,I,J,K,L](t12: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K], ST[L]))) extends RichTaskables(k12(t12)) { type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L]) => Ret def identityMap = map(mkTuple12) - protected def convertH[R](z: Fun[Id,R]) = hf12(z) - protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: k :^: l :^: KNil => z(a,b,c,d,e,f,g,h,i,j,k,l) } + protected def convert[M[_],R](z: Fun[M,R]) = z.tupled } - final class RichTaskable13[A,B,C,D,E,F,G,H,I,J,K,L,N](t13: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N]))) extends RichTaskables(k13(t13)) + final class RichTaskable13[A,B,C,D,E,F,G,H,I,J,K,L,N](t13: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K], ST[L], ST[N]))) extends RichTaskables(k13(t13)) { type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N]) => Ret def identityMap = map(mkTuple13) - protected def convertH[R](z: Fun[Id,R]) = hf13(z) - protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: k :^: l :^: n :^: KNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n) } + protected def convert[M[_],R](z: Fun[M,R]) = z.tupled } - final class RichTaskable14[A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N], ScopedTaskable[O]))) extends RichTaskables(k14(t14)) + final class RichTaskable14[A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K], ST[L], ST[N], ST[O]))) extends RichTaskables(k14(t14)) { type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N], M[O]) => Ret def identityMap = map(mkTuple14) - protected def convertH[R](z: Fun[Id,R]) = hf14(z) - protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: k :^: l :^: n :^: o :^: KNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n,o) } + protected def convert[M[_],R](z: Fun[M,R]) = z.tupled } - final class RichTaskable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N], ScopedTaskable[O], ScopedTaskable[P]))) extends RichTaskables(k15(t15)) + final class RichTaskable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K], ST[L], ST[N], ST[O], ST[P]))) extends RichTaskables(k15(t15)) { type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N], M[O], M[P]) => Ret def identityMap = map(mkTuple15) - protected def convertH[R](z: Fun[Id,R]) = hf15(z) - protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: k :^: l :^: n :^: o :^: p :^: KNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n,o,p) } - } + protected def convert[M[_],R](z: Fun[M,R]) = z.tupled + }*/ // this doesn't actually work for mixed KLists because the compiler crashes trying to infer the bound when constructing the KList - implicit def richTaskableKeys[HL <: HList](in: KList[ScopedTaskable, HL]): RichTaskableKeys[HL] = new RichTaskableKeys(in) - final class RichTaskableKeys[In <: HList](keys: KList[ScopedTaskable, In]) +/* implicit def richTaskableKeys[KL <: KList[ScopedTaskable]](in: KList): RichTaskableKeys[KL] = new RichTaskableKeys[KL](in) + final class RichTaskableKeys[KL <: KList[ScopedTaskable]](keys: KL) { type App[T] = Initialize[Task[T]] - private[this] val red = reduced(keys) + private[this] def inputs: keys.Transform[App] = keys.transform( new (ScopedTaskable ~> App) { def apply[T](in: ScopedTaskable[T]): App[T] = in.toTask }) def identity: App[In] = map(idFun) - def flatMap[T](f: In => Task[T]): App[T] = flatMapR(f compose allM) - def flatMapR[T](f: Results[In] => Task[T]): App[T] = red.combine(Combine.flatMapR, f) + def flatMap[T](f: keys.Transform[Id] => Task[T]): App[T] = flatMapR(f compose allM) + def flatMapR[T](f: keys.Transform[Result] => Task[T]): App[T] = red.combine(Combine.flatMapR, f) def map[T](f: In => T): App[T] = mapR(f compose allM) def mapR[T](f: Results[In] => T): App[T] = red.combine[Id,T](Combine.mapR, f) def flatFailure[T](f: Seq[Incomplete] => Task[T]): App[T] = flatMapR(f compose anyFailM) def mapFailure[T](f: Seq[Incomplete] => T): App[T] = mapR(f compose anyFailM) - } + }*/ implicit def t2ToApp2[A,B](t2: (Initialize[A], Initialize[B]) ): Apply2[A,B] = new Apply2(t2) implicit def t3ToApp3[A,B,C](t3: (Initialize[A], Initialize[B], Initialize[C]) ): Apply3[A,B,C] = new Apply3(t3) @@ -491,11 +422,11 @@ object Scoped implicit def t9ToApp9[A,B,C,D,E,F,G,H,I](t9: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I]) ): Apply9[A,B,C,D,E,F,G,H,I] = new Apply9(t9) implicit def t10ToApp10[A,B,C,D,E,F,G,H,I,J](t10: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J]) ): Apply10[A,B,C,D,E,F,G,H,I,J] = new Apply10(t10) implicit def t11ToApp11[A,B,C,D,E,F,G,H,I,J,K](t11: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K]) ): Apply11[A,B,C,D,E,F,G,H,I,J,K] = new Apply11(t11) - implicit def t12ToApp12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L]) ): Apply12[A,B,C,D,E,F,G,H,I,J,K,L] = new Apply12(t12) +/* implicit def t12ToApp12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L]) ): Apply12[A,B,C,D,E,F,G,H,I,J,K,L] = new Apply12(t12) implicit def t13ToApp13[A,B,C,D,E,F,G,H,I,J,K,L,N](t13: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N]) ): Apply13[A,B,C,D,E,F,G,H,I,J,K,L,N] = new Apply13(t13) implicit def t14ToApp14[A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N], Initialize[O]) ): Apply14[A,B,C,D,E,F,G,H,I,J,K,L,N,O] = new Apply14(t14) implicit def t15ToApp15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N], Initialize[O], Initialize[P]) ): Apply15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P] = new Apply15(t15) - +*/ def mkTuple2[A,B] = (a:A,b:B) => (a,b) def mkTuple3[A,B,C] = (a:A,b:B,c:C) => (a,b,c) def mkTuple4[A,B,C,D] = (a:A,b:B,c:C,d:D) => (a,b,c,d) @@ -512,46 +443,46 @@ object Scoped def mkTuple15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P] = (a:A,b:B,c:C,d:D,e:E,f:F,g:G,h:H,i:I,j:J,k:K,l:L,n:N,o:O,p:P) => (a,b,c,d,e,f,g,h,i,j,k,l,n,o,p) final class Apply2[A,B](t2: (Initialize[A], Initialize[B])) { - def apply[T](z: (A,B) => T) = Def.app( k2(t2) )( hf2(z) ) + def apply[T](z: (A,B) => T) = Def.app[AList.T2K[A,B]#l, T]( t2 )( z.tupled )(AList.tuple2[A,B]) def identity = apply(mkTuple2) } final class Apply3[A,B,C](t3: (Initialize[A], Initialize[B], Initialize[C])) { - def apply[T](z: (A,B,C) => T) = Def.app( k3(t3) )( hf3(z) ) + def apply[T](z: (A,B,C) => T) = Def.app[AList.T3K[A,B,C]#l, T]( t3 )( z.tupled )(AList.tuple3[A,B,C]) def identity = apply(mkTuple3) } final class Apply4[A,B,C,D](t4: (Initialize[A], Initialize[B], Initialize[C], Initialize[D])) { - def apply[T](z: (A,B,C,D) => T) = Def.app( k4(t4) )( hf4(z) ) + def apply[T](z: (A,B,C,D) => T) = Def.app[AList.T4K[A,B,C,D]#l, T]( t4 )( z.tupled )(AList.tuple4[A,B,C,D]) def identity = apply(mkTuple4) } final class Apply5[A,B,C,D,E](t5: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E])) { - def apply[T](z: (A,B,C,D,E) => T) = Def.app( k5(t5) )( hf5(z) ) + def apply[T](z: (A,B,C,D,E) => T) = Def.app[AList.T5K[A,B,C,D,E]#l, T]( t5 )( z.tupled )( AList.tuple5[A,B,C,D,E] ) def identity = apply(mkTuple5) } final class Apply6[A,B,C,D,E,F](t6: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F])) { - def apply[T](z: (A,B,C,D,E,F) => T) = Def.app( k6(t6) )( hf6(z) ) + def apply[T](z: (A,B,C,D,E,F) => T) = Def.app[AList.T6K[A,B,C,D,E,F]#l, T]( t6 )( z.tupled )( AList.tuple6[A,B,C,D,E,F] ) def identity = apply(mkTuple6) } final class Apply7[A,B,C,D,E,F,G](t7: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G])) { - def apply[T](z: (A,B,C,D,E,F,G) => T) = Def.app( k7(t7) )( hf7(z) ) + def apply[T](z: (A,B,C,D,E,F,G) => T) = Def.app[AList.T7K[A,B,C,D,E,F,G]#l, T]( t7 )( z.tupled )( AList.tuple7[A,B,C,D,E,F,G] ) def identity = apply(mkTuple7) } final class Apply8[A,B,C,D,E,F,G,H](t8: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H])) { - def apply[T](z: (A,B,C,D,E,F,G,H) => T) = Def.app( k8(t8) )( hf8(z) ) + def apply[T](z: (A,B,C,D,E,F,G,H) => T) = Def.app[AList.T8K[A,B,C,D,E,F,G,H]#l, T]( t8 )( z.tupled )( AList.tuple8[A,B,C,D,E,F,G,H] ) def identity = apply(mkTuple8) } final class Apply9[A,B,C,D,E,F,G,H,I](t9: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I])) { - def apply[T](z: (A,B,C,D,E,F,G,H,I) => T) = Def.app( k9(t9) )( hf9(z) ) + def apply[T](z: (A,B,C,D,E,F,G,H,I) => T) = Def.app[AList.T9K[A,B,C,D,E,F,G,H,I]#l, T]( t9 )( z.tupled )( AList.tuple9[A,B,C,D,E,F,G,H,I] ) def identity = apply(mkTuple9) } final class Apply10[A,B,C,D,E,F,G,H,I,J](t10: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J])) { - def apply[T](z: (A,B,C,D,E,F,G,H,I,J) => T) = Def.app( k10(t10) )( hf10(z) ) + def apply[T](z: (A,B,C,D,E,F,G,H,I,J) => T) = Def.app[AList.T10K[A,B,C,D,E,F,G,H,I,J]#l, T]( t10 )( z.tupled )( AList.tuple10[A,B,C,D,E,F,G,H,I,J] ) def identity = apply(mkTuple10) } final class Apply11[A,B,C,D,E,F,G,H,I,J,K](t11: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K])) { - def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K) => T) = Def.app( k11(t11) )( hf11(z) ) + def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K) => T) = Def.app[AList.T11K[A,B,C,D,E,F,G,H,I,J,K]#l, T]( t11 )( z.tupled )( AList.tuple11[A,B,C,D,E,F,G,H,I,J,K] ) def identity = apply(mkTuple11) } - final class Apply12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L])) { +/* final class Apply12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L])) { def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L) => T) = Def.app( k12(t12) )( hf12(z) ) def identity = apply(mkTuple12) } @@ -567,38 +498,7 @@ object Scoped def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N,O,P) => T) = Def.app( k15(t15) )( hf15(z) ) def identity = apply(mkTuple15) } - - def hf2[A, B, T](z: (A, B) => T): A :+: B :+: HNil => T = { case a :+: b :+: HNil => z(a,b) } - def hf3[A, B, C, T](z: (A,B,C) => T): A :+: B :+: C :+: HNil => T = { case a :+: b :+: c :+: HNil => z(a,b,c) } - def hf4[A, B, C, D, T](z: (A,B,C,D) => T): A :+: B :+: C :+: D :+: HNil => T = { case a :+: b :+: c :+: d :+: HNil => z(a,b,c,d) } - def hf5[A, B, C, D, E, T](z: (A,B,C,D,E) => T): A :+: B :+: C :+: D :+: E :+: HNil => T = { case a :+: b :+: c :+: d :+: e :+: HNil => z(a,b,c,d,e) } - def hf6[A, B, C, D, E, F, T](z: (A,B,C,D,E,F) => T): A :+: B :+: C :+: D :+: E :+: F :+: HNil => T = { case a :+: b :+: c :+: d :+: e :+: f :+: HNil => z(a,b,c,d,e,f) } - def hf7[A, B, C, D, E, F, G, T](z: (A,B,C,D,E,F,G) => T): A :+: B :+: C :+: D :+: E :+: F :+: G :+: HNil => T = { case a :+: b :+: c :+: d :+: e :+: f :+: g :+: HNil => z(a,b,c,d,e,f,g) } - def hf8[A, B, C, D, E, F, G, H, T](z: (A,B,C,D,E,F,G,H) => T): A :+: B :+: C :+: D :+: E :+: F :+: G :+: H :+: HNil => T = { case a :+: b :+: c :+: d :+: e :+: f :+: g :+: h :+: HNil => z(a,b,c,d,e,f,g,h) } - def hf9[A, B, C, D, E, F, G, H, I, T](z: (A,B,C,D,E,F,G,H,I) => T): A :+: B :+: C :+: D :+: E :+: F :+: G :+: H :+: I :+: HNil => T = { case a :+: b :+: c :+: d :+: e :+: f :+: g :+: h :+: i :+: HNil => z(a,b,c,d,e,f,g,h,i) } - def hf10[A,B,C,D,E,F,G,H,I,J,T](z: (A,B,C,D,E,F,G,H,I,J) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j :+: HNil => z(a,b,c,d,e,f,g,h,i,j) } - def hf11[A,B,C,D,E,F,G,H,I,J,K,T](z: (A,B,C,D,E,F,G,H,I,J,K) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J:+:K :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j:+:k :+: HNil => z(a,b,c,d,e,f,g,h,i,j,k) } - def hf12[A,B,C,D,E,F,G,H,I,J,K,L,T](z: (A,B,C,D,E,F,G,H,I,J,K,L) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J:+:K:+:L :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j:+:k:+:l :+: HNil => z(a,b,c,d,e,f,g,h,i,j,k,l) } - def hf13[A,B,C,D,E,F,G,H,I,J,K,L,N,T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J:+:K:+:L:+:N :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j:+:k:+:l:+:n :+: HNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n) } - def hf14[A,B,C,D,E,F,G,H,I,J,K,L,N,O,T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N,O) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J:+:K:+:L:+:N:+:O :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j:+:k:+:l:+:n:+:o :+: HNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n,o) } - def hf15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P,T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N,O,P) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J:+:K:+:L:+:N:+:O:+:P :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j:+:k:+:l:+:n:+:o:+:p :+: HNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n,o,p) } - - - def k2[M[_], A, B](t2: (M[A], M[B]) ) = t2._1 :^: t2._2 :^: KNil - def k3[M[_], A, B, C](t3: (M[A], M[B], M[C]) ) = t3._1 :^: t3._2 :^: t3._3 :^: KNil - def k4[M[_], A, B, C, D](t4: (M[A], M[B], M[C], M[D])) = t4._1 :^: t4._2 :^: t4._3 :^: t4._4 :^: KNil - def k5[M[_], A, B, C, D, E](t5: (M[A], M[B], M[C], M[D], M[E])) = t5._1 :^: t5._2 :^: t5._3 :^: t5._4 :^: t5._5 :^: KNil - def k6[M[_], A, B, C, D, E, F](t6: (M[A], M[B], M[C], M[D], M[E], M[F])) = t6._1 :^: t6._2 :^: t6._3 :^: t6._4 :^: t6._5 :^: t6._6 :^: KNil - def k7[M[_], A, B, C, D, E, F, G](t7: (M[A], M[B], M[C], M[D], M[E], M[F], M[G])) = t7._1 :^: t7._2 :^: t7._3 :^: t7._4 :^: t7._5 :^: t7._6 :^: t7._7 :^: KNil - def k8[M[_], A, B, C, D, E, F, G, H](t8: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H])) = t8._1 :^: t8._2 :^: t8._3 :^: t8._4 :^: t8._5 :^: t8._6 :^: t8._7 :^: t8._8 :^: KNil - def k9[M[_], A, B, C, D, E, F, G, H, I](t9: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I])) = t9._1 :^: t9._2 :^: t9._3 :^: t9._4 :^: t9._5 :^: t9._6 :^: t9._7 :^: t9._8 :^: t9._9 :^: KNil - def k10[M[_], A,B,C,D,E,F,G,H,I,J](t10: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J])) =t10._1 :^:t10._2 :^:t10._3 :^:t10._4 :^:t10._5 :^:t10._6 :^:t10._7 :^:t10._8 :^:t10._9 :^:t10._10 :^: KNil - def k11[M[_], A,B,C,D,E,F,G,H,I,J,K](t11: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K])) =t11._1 :^:t11._2 :^:t11._3 :^:t11._4 :^:t11._5 :^:t11._6 :^:t11._7 :^:t11._8 :^:t11._9 :^:t11._10 :^:t11._11 :^: KNil - def k12[M[_], A,B,C,D,E,F,G,H,I,J,K,L](t12: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L])) =t12._1 :^:t12._2 :^:t12._3 :^:t12._4 :^:t12._5 :^:t12._6 :^:t12._7 :^:t12._8 :^:t12._9 :^:t12._10 :^:t12._11 :^:t12._12 :^: KNil - def k13[M[_], A,B,C,D,E,F,G,H,I,J,K,L,N](t13: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N])) =t13._1 :^:t13._2 :^:t13._3 :^:t13._4 :^:t13._5 :^:t13._6 :^:t13._7 :^:t13._8 :^:t13._9 :^:t13._10 :^:t13._11 :^:t13._12 :^:t13._13 :^: KNil - def k14[M[_], A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N], M[O])) =t14._1 :^:t14._2 :^:t14._3 :^:t14._4 :^:t14._5 :^:t14._6 :^:t14._7 :^:t14._8 :^:t14._9 :^:t14._10 :^:t14._11 :^:t14._12 :^:t14._13 :^:t14._14 :^: KNil - def k15[M[_], A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N], M[O], M[P])) =t15._1 :^:t15._2 :^:t15._3 :^:t15._4 :^:t15._5 :^:t15._6 :^:t15._7 :^:t15._8 :^:t15._9 :^:t15._10 :^:t15._11 :^:t15._12 :^:t15._13 :^:t15._14 :^:t15._15 :^: KNil - +*/ private[sbt] def extendScoped(s1: Scoped, ss: Seq[Scoped]): Seq[AttributeKey[_]] = s1.key +: ss.map(_.key) } diff --git a/main/src/test/scala/ParseKey.scala b/main/src/test/scala/ParseKey.scala index aa15b09fc..45a1558ee 100644 --- a/main/src/test/scala/ParseKey.scala +++ b/main/src/test/scala/ParseKey.scala @@ -1,6 +1,6 @@ package sbt - import Project._ + import Def.{displayFull,displayMasked,ScopedKey} import java.net.URI import TestBuild._ import complete._ @@ -10,7 +10,7 @@ package sbt import Prop._ import Arbitrary.arbBool -/** Tests that the scoped key parser in Act can correctly parse a ScopedKey converted by Project.show*Key. +/** Tests that the scoped key parser in Act can correctly parse a ScopedKey converted by Def.show*Key. * This includes properly resolving omitted components.*/ object ParseKey extends Properties("Key parser test") { @@ -24,9 +24,9 @@ object ParseKey extends Properties("Key parser test") import skm.{structure, key, mask} val expected = resolve(structure, key, mask) - val string = Project.displayMasked(key, mask) + val string = displayMasked(key, mask) - ("Key: " + Project.displayFull(key)) |: + ("Key: " + displayFull(key)) |: parseExpected(structure, string, expected, mask) } @@ -35,9 +35,9 @@ object ParseKey extends Properties("Key parser test") import skm.{structure, key} val mask = skm.mask.copy(project = false) - val string = Project.displayMasked(key, mask) + val string = displayMasked(key, mask) - ("Key: " + Project.displayFull(key)) |: + ("Key: " + displayFull(key)) |: ("Mask: " + mask) |: ("Current: " + structure.current) |: parse(structure, string) { @@ -50,9 +50,9 @@ object ParseKey extends Properties("Key parser test") forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) => import skm.{structure, key} val mask = skm.mask.copy(task = false) - val string = Project.displayMasked(key, mask) + val string = displayMasked(key, mask) - ("Key: " + Project.displayFull(key)) |: + ("Key: " + displayFull(key)) |: ("Mask: " + mask) |: parse(structure, string) { case Left(err) => false @@ -64,10 +64,10 @@ object ParseKey extends Properties("Key parser test") forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) => import skm.{structure, key} val mask = ScopeMask(config = false) - val string = Project.displayMasked(key, mask) + val string = displayMasked(key, mask) val resolvedConfig = Resolve.resolveConfig(structure.extra, key.key, mask)(key.scope).config - ("Key: " + Project.displayFull(key)) |: + ("Key: " + displayFull(key)) |: ("Mask: " + mask) |: ("Expected configuration: " + resolvedConfig.map(_.name)) |: parse(structure, string) { @@ -88,7 +88,7 @@ object ParseKey extends Properties("Key parser test") ScopedKey(Resolve(structure.extra, Select(structure.current), key.key, mask)(key.scope), key.key) def parseExpected(structure: Structure, s: String, expected: ScopedKey[_], mask: ScopeMask): Prop = - ("Expected: " + Project.displayFull(expected)) |: + ("Expected: " + displayFull(expected)) |: ("Mask: " + mask) |: parse(structure, s) { case Left(err) => false @@ -99,7 +99,7 @@ object ParseKey extends Properties("Key parser test") { val parser = makeParser(structure) val parsed = DefaultParsers.result(parser, s).left.map(_().toString) - val showParsed = parsed.right.map(Project.displayFull) + val showParsed = parsed.right.map(displayFull) ("Key string: '" + s + "'") |: ("Parsed: " + showParsed) |: ("Structure: " + structure) |: @@ -108,7 +108,7 @@ object ParseKey extends Properties("Key parser test") def genStructure(implicit genEnv: Gen[Env]): Gen[Structure] = structureGenF { (scopes: Seq[Scope], env: Env, current: ProjectRef) => - val settings = for(scope <- scopes; t <- env.tasks) yield Project.setting(ScopedKey(scope, t.key), Project.value("")) + val settings = for(scope <- scopes; t <- env.tasks) yield Def.setting(ScopedKey(scope, t.key), Def.value("")) TestBuild.structure(env, settings, current) } diff --git a/main/src/test/scala/TestBuild.scala b/main/src/test/scala/TestBuild.scala index 56caee148..b1eeaeeec 100644 --- a/main/src/test/scala/TestBuild.scala +++ b/main/src/test/scala/TestBuild.scala @@ -1,6 +1,6 @@ package sbt - import Project._ + import Def.{ScopedKey, Setting} import Types.{const,idFun,some} import complete.Parser @@ -184,7 +184,7 @@ object TestBuild def structure(env: Env, settings: Seq[Setting[_]], current: ProjectRef): Structure = { - implicit val display = Project.showRelativeKey(current, env.allProjects.size > 1) + implicit val display = Def.showRelativeKey(current, env.allProjects.size > 1) val data = Project.makeSettings(settings, env.delegates, const(Nil)) val keys = data.allKeys( (s, key) => ScopedKey(s, key)) val keyMap = keys.map(k => (k.key.label, k.key)).toMap[String, AttributeKey[_]] diff --git a/project/Sbt.scala b/project/Sbt.scala index c9fd2ef7e..65481f3ef 100644 --- a/project/Sbt.scala +++ b/project/Sbt.scala @@ -16,7 +16,7 @@ object Sbt extends Build organization := "org.scala-sbt", version := "0.13.0-SNAPSHOT", publishArtifact in packageDoc := false, - scalaVersion := "2.9.2", + scalaVersion := "2.10.0-M5", publishMavenStyle := false, componentID := None, crossPaths := false, @@ -96,7 +96,7 @@ object Sbt extends Build // Includes API and Analyzer phases that extract source API and relationships. lazy val compileInterfaceSub = baseProject(compilePath / "interface", "Compiler Interface") dependsOn(interfaceSub, ioSub % "test->test", logSub % "test->test", launchSub % "test->test") settings( compileInterfaceSettings : _*) lazy val precompiled282 = precompiled("2.8.2") - lazy val precompiled2100 = precompiled("2.10.0-RC2") + lazy val precompiled292 = precompiled("2.9.2") // Implements the core functionality of detecting and propagating changes incrementally. // Defines the data structures for representing file fingerprints and relationships and the overall source analysis @@ -132,7 +132,7 @@ object Sbt extends Build // Strictly for bringing implicits and aliases from subsystems into the top-level sbt namespace through a single package object // technically, we need a dependency on all of mainSub's dependencies, but we don't do that since this is strictly an integration project // with the sole purpose of providing certain identifiers without qualification (with a package object) - lazy val sbtSub = baseProject(sbtPath, "Simple Build Tool") dependsOn(mainSub, compileInterfaceSub, precompiled282, precompiled2100, scriptedSbtSub % "test->test") settings(sbtSettings : _*) + lazy val sbtSub = baseProject(sbtPath, "Simple Build Tool") dependsOn(mainSub, compileInterfaceSub, precompiled282, precompiled292, scriptedSbtSub % "test->test") settings(sbtSettings : _*) /* Nested subproject paths */ def sbtPath = file("sbt") @@ -249,5 +249,10 @@ object Sbt extends Build libraryDependencies <+= scalaVersion( "org.scala-lang" % "scala-compiler" % _ % "test"), unmanagedJars in Test <<= (packageSrc in compileInterfaceSub in Compile).map(x => Seq(x).classpath) ) - def precompiled(scalav: String): Project = baseProject(compilePath / "interface", "Precompiled " + scalav.replace('.', '_')) dependsOn(interfaceSub) settings(scalaVersion := scalav) settings(precompiledSettings : _*) + def precompiled(scalav: String): Project = baseProject(compilePath / "interface", "Precompiled " + scalav.replace('.', '_')) dependsOn(interfaceSub) settings(precompiledSettings : _*) settings( + scalaVersion <<= (scalaVersion in ThisBuild) { sbtScalaV => + assert(sbtScalaV != scalav, "Precompiled compiler interface cannot have the same Scala version (" + scalav + ") as sbt.") + scalav + } + ) } diff --git a/project/Util.scala b/project/Util.scala index ac7f8e6f6..41c2308a4 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -30,7 +30,7 @@ object Util lazy val base: Seq[Setting[_]] = Seq(scalacOptions ++= Seq("-Xelide-below", "0"), projectComponent) ++ Licensed.settings def testDependencies = libraryDependencies ++= Seq( - "org.scala-tools.testing" % "scalacheck_2.9.1" % "1.9" % "test", + "org.scalacheck" % "scalacheck_2.10.0-M5" % "1.10.0" % "test", "org.scala-tools.testing" % "specs_2.9.1" % "1.6.9" % "test" ) diff --git a/sbt/package.scala b/sbt/package.scala index aac8f986f..84b5dfad0 100644 --- a/sbt/package.scala +++ b/sbt/package.scala @@ -14,9 +14,9 @@ package object sbt extends sbt.std.TaskExtra with sbt.Types with sbt.ProcessExtr @deprecated("Use InputKey, which is a drop-in replacement.", "0.11.1") type ScopedInput[T] = InputKey[T] - type Setting[T] = Project.Setting[T] - type ScopedKey[T] = Project.ScopedKey[T] - type SettingsDefinition = Project.SettingsDefinition + type Setting[T] = Def.Setting[T] + type ScopedKey[T] = Def.ScopedKey[T] + type SettingsDefinition = Def.SettingsDefinition type File = java.io.File type URI = java.net.URI type URL = java.net.URL diff --git a/scripted/plugin/ScriptedPlugin.scala b/scripted/plugin/ScriptedPlugin.scala index 58b463a0d..f3286ede6 100644 --- a/scripted/plugin/ScriptedPlugin.scala +++ b/scripted/plugin/ScriptedPlugin.scala @@ -3,7 +3,7 @@ */ package sbt -import Project.Initialize +import Def.Initialize import Keys._ import classpath.ClasspathUtilities import java.lang.reflect.Method diff --git a/tasks/Execute.scala b/tasks/Execute.scala index 457b0221f..35a510fae 100644 --- a/tasks/Execute.scala +++ b/tasks/Execute.scala @@ -227,9 +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 getResult - val ud = v.uniformIn.map(getResult.apply[v.Uniform]) - strategy.submit( node, () => work(node, v.work(rs, ud)) ) + val rs = v.alist.transform(v.in, getResult) + strategy.submit( node, () => work(node, v.work(rs)) ) } /** Evaluates the computation 'f' for 'node'. * This returns a Completed instance, which contains the post-processing to perform after the result is retrieved from the Strategy.*/ @@ -254,7 +253,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).filter(dep => view.inline(dep).isEmpty) + def dependencies(v: Node[A, _]): Iterable[A[_]] = v.alist.toList(v.in).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) diff --git a/tasks/Node.scala b/tasks/Node.scala index 6e5fa4ca4..0e1de16e4 100644 --- a/tasks/Node.scala +++ b/tasks/Node.scala @@ -6,18 +6,15 @@ package sbt import Types._ /** Represents a task node in a format understood by the task evaluation engine Execute. -* Heterogenous inputs (Mixed, tuple) and homogeneous (Uniform, sequence) are defined and consumed separately. * -* @tparam A the task type +* @tparam A the task type constructor * @tparam T the type computed by this node */ trait Node[A[_], T] { - type Mixed <: HList - type Uniform - - val mixedIn: KList[A, Mixed] - val uniformIn: Seq[A[Uniform]] + type K[L[x]] + val in: K[A] + val alist: AList[K] /** Computes the result of this task given the results from the inputs. */ - def work(mixed: KList[Result, Mixed], uniform: Seq[Result[Uniform]]): Either[A[T], T] + def work(inputs: K[Result]): Either[A[T], T] } diff --git a/tasks/src/test/scala/DemoTask.scala b/tasks/src/test/scala/DemoTask.scala deleted file mode 100644 index 9ebae6b8a..000000000 --- a/tasks/src/test/scala/DemoTask.scala +++ /dev/null @@ -1,163 +0,0 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah - */ -package sbt - -import Types._ -import Task._ -import Execute._ - -sealed trait Task[+T] -sealed case class Pure[+T](eval: () => T) extends Task[T] -final case class Mapped[+T, In <: HList](in: Tasks[In], f: Results[In] => T) extends Task[T] -final case class MapAll[+T, In <: HList](in: Tasks[In], f: In => T) extends Task[T] -final case class FlatMapAll[+T, In <: HList](in: Tasks[In], f: In => Task[T]) extends Task[T] -final case class MapFailure[+T, In <: HList](in: Tasks[In], f: Seq[Incomplete] => T) extends Task[T] -final case class FlatMapFailure[+T, In <: HList](in: Tasks[In], f: Seq[Incomplete] => Task[T]) extends Task[T] -final case class FlatMapped[+T, In <: HList](in: Tasks[In], f: Results[In] => Task[T]) extends Task[T] -final case class DependsOn[+T](in: Task[T], deps: Seq[Task[_]]) extends Task[T] -final case class Join[+T, U](in: Seq[Task[U]], f: Seq[U] => Either[Task[T], T]) extends Task[T] { type Uniform = U } - -trait MultiInTask[In <: HList] -{ - def flatMap[T](f: In => Task[T]): Task[T] - def flatMapR[T](f: Results[In] => Task[T]): Task[T] - def mapH[T](f: In => T): Task[T] - def mapR[T](f: Results[In] => T): Task[T] - def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T] - def mapFailure[T](f: Seq[Incomplete] => T): Task[T] -} -trait SingleInTask[S] -{ - def flatMapR[T](f: Result[S] => Task[T]): Task[T] - def flatMap[T](f: S => Task[T]): Task[T] - def map[T](f: S => T): Task[T] - def mapR[T](f: Result[S] => T): Task[T] - def flatFailure[T](f: Incomplete => Task[T]): Task[T] - def mapFailure[T](f: Incomplete => T): Task[T] - def dependsOn(tasks: Task[_]*): Task[S] -} -trait ForkTask[S, CC[_]] -{ - def fork[T](f: S => T): CC[Task[T]] -} -trait JoinTask[S, CC[_]] -{ - def join: Task[CC[S]] - def reduced(f: (S,S) => S): Task[S] -} -object Task -{ - type Tasks[HL <: HList] = KList[Task, HL] - type Results[HL <: HList] = KList[Result, HL] - - def pure[T](f: => T): Task[T] = toPure(f _) - def pure[T](name: String, f: => T): Task[T] = new Pure(f _) { override def toString = name } - implicit def toPure[T](f: () => T): Task[T] = new Pure(f) - - implicit def pureTasks[S](in: Seq[S]): Seq[Task[S]] = in.map(s => pure(s)) - implicit def toTasks[S](in: Seq[() => S]): Seq[Task[S]] = in.map(toPure) - implicit def iterableTask[S](in: Seq[S]): ForkTask[S, Seq] = new ForkTask[S, Seq] { - def fork[T](f: S => T): Seq[Task[T]] = in.map(x => pure(x) map f) - } - implicit def pureJoin[S](in: Seq[S]): JoinTask[S, Seq] = joinTasks(pureTasks(in)) - implicit def joinTasks[S](in: Seq[Task[S]]): JoinTask[S, Seq] = new JoinTask[S, Seq] { - def join: Task[Seq[S]] = new Join(in, (s: Seq[S]) => Right(s) ) - //def join[T](f: Iterable[S] => T): Task[Iterable[T]] = new MapAll( MList.fromTCList[Task](in), ml => f(ml.toList)) - //def joinR[T](f: Iterable[Result[S]] => T): Task[Iterable[Result[T]]] = new Mapped( MList.fromTCList[Task](in), ml => f(ml.toList)) - def reduced(f: (S,S) => S): Task[S] = Task.reduced(in.toIndexedSeq, f) - } - - - implicit def multInputTask[In <: HList](tasks: Tasks[In]): MultiInTask[In] = new MultiInTask[In] { - def flatMap[T](f: In => Task[T]): Task[T] = new FlatMapAll(tasks, f) - def flatMapR[T](f: Results[In] => Task[T]): Task[T] = new FlatMapped(tasks, f) - def mapH[T](f: In => T): Task[T] = new MapAll(tasks, f) - def mapR[T](f: Results[In] => T): Task[T] = new Mapped(tasks, f) - def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T] = new FlatMapFailure(tasks, f) - def mapFailure[T](f: Seq[Incomplete] => T): Task[T] = new MapFailure(tasks, f) - } - implicit def singleInputTask[S](in: Task[S]): SingleInTask[S] = new SingleInTask[S] { - type HL = S :+: HNil - private val ml = in :^: KNil - private def headM = (_: Results[HL]).combine.head - private def headH = (_: HL).head - private def headS = (_: Seq[Incomplete]).head - def flatMapR[T](f: Result[S] => Task[T]): Task[T] = new FlatMapped[T, HL](ml, f ∙ headM) - def flatMap[T](f: S => Task[T]): Task[T] = new FlatMapAll(ml, f ∙ headH) - def map[T](f: S => T): Task[T] = new MapAll(ml, f ∙ headH) - def mapR[T](f: Result[S] => T): Task[T] = new Mapped[T, HL](ml, f ∙ headM) - def flatFailure[T](f: Incomplete => Task[T]): Task[T] = new FlatMapFailure(ml, f ∙ headS) - def mapFailure[T](f: Incomplete => T): Task[T] = new MapFailure(ml, f ∙ headS) - def dependsOn(tasks: Task[_]*): Task[S] = new DependsOn(in, tasks) - } - - implicit val taskToNode = new NodeView[Task] { - def inline[T](a: Task[T]): Option[() => T] = None - def apply[T](t: Task[T]): Node[Task, T] = t match { - case Pure(eval) => toNode[T, HNil](KNil, _ => Right(eval()) ) - case Mapped(in, f) => toNode(in, right ∙ f ) - case MapAll(in, f) => toNode[T, in.Raw](in, right ∙ (f compose allM) ) - case MapFailure(in, f) => toNode[T, in.Raw](in, right ∙ (f compose failuresM)) - case FlatMapped(in, f) => toNode(in, left ∙ f ) - case FlatMapAll(in, f) => toNode[T, in.Raw](in, left ∙ (f compose allM) ) - case FlatMapFailure(in, f) => toNode[T, in.Raw](in, left ∙ (f compose failuresM)) - case DependsOn(in, tasks) => join[T, Any](tasks, (_: Seq[Result[_]]) => Left(in)) - case j@ Join(in, f) => join[T, j.Uniform](in, f compose all) - } - } - def join[T, D](tasks: Seq[Task[D]], f: Seq[Result[D]] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] { - type Mixed = HNil - val mixedIn = KNil - type Uniform = D - val uniformIn = tasks - def work(mixed: Results[HNil], uniform: Seq[Result[Uniform]]) = { - val inc = failures(uniform) - if(inc.isEmpty) f(uniform) else throw Incomplete(None, causes = inc) - } - } - def toNode[T, In <: HList](in: Tasks[In], f: Results[In] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] { - type Mixed = In - val mixedIn = in - type Uniform = Nothing - val uniformIn = Nil - def work(results: Results[In], units: Seq[Result[Uniform]]) = f(results) - } - def allM[In <: HList]: Results[In] => In = in => - { - val incs = failuresM(in) - if(incs.isEmpty) in.down(Result.tryValue) else throw Incomplete(None, causes = incs) - } - def all[D]: Seq[Result[D]] => Seq[D] = in => - { - val incs = failures(in) - if(incs.isEmpty) in.map(Result.tryValue.apply[D]) else throw Incomplete(None, causes = incs) - } - def failuresM[In <: HList]: Results[In] => Seq[Incomplete] = x => failures[Any](x.toList) - def failures[A]: Seq[Result[A]] => Seq[Incomplete] = _.collect { case Inc(i) => i } - - def run[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): Result[T] = - { - val (service, shutdown) = CompletionService[Task[_], Completed](maxWorkers) - val x = new Execute[Task](checkCycles, Execute.noTriggers)(taskToNode) - try { x.run(root)(service) } finally { shutdown() } - } - def tryRun[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): T = - run(root, checkCycles, maxWorkers) match { - case Value(v) => v - case Inc(i) => throw i - } - - def reduced[S](i: IndexedSeq[Task[S]], f: (S, S) => S): Task[S] = - i match - { - case Seq() => error("Cannot reduce empty sequence") - case Seq(x) => x - case Seq(x, y) => reducePair(x, y, f) - case z => - val (a, b) = i.splitAt(i.size / 2) - reducePair( reduced(a, f), reduced(b, f), f ) - } - def reducePair[S](a: Task[S], b: Task[S], f: (S, S) => S): Task[S] = - (a :^: b :^: KNil) mapH { case x :+: y :+: HNil => f(x,y) } -} \ No newline at end of file diff --git a/tasks/src/test/scala/TaskGen.scala b/tasks/src/test/scala/TaskGen.scala deleted file mode 100644 index 482cfa7de..000000000 --- a/tasks/src/test/scala/TaskGen.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* sbt -- Simple Build Tool - * Copyright 2009 Mark Harrah - */ -package sbt - -import org.scalacheck._ -import Gen.choose - -object TaskGen -{ - // upper bounds to make the tests finish in reasonable time - val MaxTasks = 100 - val MaxWorkers = 29 - val MaxJoin = 20 - - val MaxTasksGen = choose(0, MaxTasks) - val MaxWorkersGen = choose(1, MaxWorkers) - val MaxJoinGen = choose(0, MaxJoin) - val TaskListGen = MaxTasksGen.flatMap(size => Gen.listOfN(size, Arbitrary.arbInt.arbitrary)) - -} \ No newline at end of file diff --git a/tasks/src/test/scala/Test.scala b/tasks/src/test/scala/Test.scala deleted file mode 100644 index 31c38625b..000000000 --- a/tasks/src/test/scala/Test.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah - */ -package sbt - -import Types._ -import Task._ -import Execute._ - -object Test -{ - val a = pure(3) - val b = pure[Boolean](error("test")) - val b2 = pure(true) - val c = pure("asdf") - val i3 = a :^: b :^: c :^: KNil - val i32 = a :^: b2 :^: c :^: KNil - - val fh= (_: Int :+: Boolean :+: String :+: HNil) match - { case aa :+: bb :+: cc :+: HNil => aa + " " + bb + " " + cc } - val h1 = i3 mapH fh - val h2 = i32 mapH fh - - type Values = Results[i3.Raw] - - val f: Values => Any = { - case Value(aa) :^: Value(bb) :^: Value(cc) :^: KNil => aa + " " + bb + " " + cc - case x => - val cs = x.toList.collect { case Inc(x) => x } // workaround for double definition bug - throw Incomplete(None, causes = cs) - } - val d2 = i32 mapR f - val f2: Values => Task[Any] = { - case Value(aa) :^: Value(bb) :^: Value(cc) :^: KNil => new Pure(() => aa + " " + bb + " " + cc) - case x => d3 - } - lazy val d = i3 flatMapR f2 - val f3: Values => Task[Any] = { - case Value(aa) :^: Value(bb) :^: Value(cc) :^: KNil => new Pure(() => aa + " " + bb + " " + cc) - case x => d2 - } - lazy val d3= i3 flatMapR f3 - - def d4(i: Int): Task[Int] = KNil flatMap { _ => val x = math.random; if(x < 0.01) pure(i); else d4(i+1) } - - def go() - { - def run[T](root: Task[T]) = - println("Result : " + Task.run(root, true, 2)) - - run(a) - run(b) - run(b2) - run(c) - run(d) - run(d2) - run( d4(0) ) - run(h1) - run(h2) - } -} \ No newline at end of file diff --git a/tasks/standard/Action.scala b/tasks/standard/Action.scala index ef086ba4d..5cec0b46b 100644 --- a/tasks/standard/Action.scala +++ b/tasks/standard/Action.scala @@ -12,26 +12,25 @@ package sbt /** Defines a task compuation*/ sealed trait 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] +final case class Mapped[T, K[L[x]]](in: K[Task], f: K[Result] => T, alist: AList[K]) extends Action[T] + /** Computes another task to evaluate based on results from evaluating other tasks.*/ -final case class FlatMapped[T, In <: HList](in: Tasks[In], f: Results[In] => Task[T]) extends Action[T] +final case class FlatMapped[T, K[L[x]]](in: K[Task], f: K[Result] => Task[T], alist: AList[K]) extends Action[T] + /** A computation `in` that requires other tasks `deps` to be evaluated first.*/ final case class DependsOn[T](in: Task[T], deps: Seq[Task[_]]) extends Action[T] + /** A computation that operates on the results of a homogeneous list of other tasks. * It can either return another task to be evaluated or the final value.*/ final case class Join[T, U](in: Seq[Task[U]], f: Seq[Result[U]] => Either[Task[T], T]) extends Action[T] -object Task -{ - type Tasks[HL <: HList] = KList[Task, HL] - type Results[HL <: HList] = KList[Result, HL] -} - /** Combines metadata `info` and a computation `work` to define a task. */ final case class Task[T](info: Info[T], work: Action[T]) { @@ -42,6 +41,7 @@ final case class Task[T](info: Info[T], work: Action[T]) def tagw(tags: (Tag, Int)*): Task[T] = copy(info = info.set(tagsKey, info.get(tagsKey).getOrElse(Map.empty) ++ tags )) def tags: TagMap = info get tagsKey getOrElse Map.empty } + /** Used to provide information about a task, such as the name, description, and tags for controlling concurrent execution. * @param attributes Arbitrary user-defined key/value pairs describing this task * @param post a transformation that takes the result of evaluating this task and produces user-defined key/value pairs. */ diff --git a/tasks/standard/System.scala b/tasks/standard/System.scala index c47881527..473970473 100644 --- a/tasks/standard/System.scala +++ b/tasks/standard/System.scala @@ -6,7 +6,7 @@ package std import Types._ import Task._ -import TaskExtra.allM +import TaskExtra.{all,existToAny} import Execute._ object Transform @@ -16,17 +16,15 @@ object Transform 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) } - def dummyMap[HL <: HList](dummies: KList[Task, HL])(inject: HL): Task ~>| Task = + final case class DummyTaskMap(mappings: List[TaskAndValue[_]]) { + def ::[T](tav: (Task[T], T)): DummyTaskMap = DummyTaskMap(new TaskAndValue(tav._1, tav._2) :: mappings) + } + final class TaskAndValue[T](val task: Task[T], val value: T) + def dummyMap(dummyMap: DummyTaskMap): Task ~>| Task = { val pmap = new DelegatingPMap[Task, Task](new collection.mutable.ListMap) - def loop[HL <: HList](ds: KList[Task, HL], vs: HL): Unit = - (ds, vs) match { - case (KCons(dh, dt), vh :+: vt) => - pmap(dh) = fromDummyStrict(dh, vh) - loop(dt, vt) - case _ => () - } - loop(dummies, inject) + def add[T](dummy: TaskAndValue[T]) { pmap(dummy.task) = fromDummyStrict(dummy.task, dummy.value) } + dummyMap.mappings.foreach(x => add(x)) pmap } @@ -36,18 +34,18 @@ object Transform def apply[T](in: Task[T]): Task[T] = map(in).getOrElse(in) } - def apply[HL <: HList, Key](dummies: KList[Task, HL], injected: HL) = + def apply(dummies: DummyTaskMap) = { import System._ - taskToNode( getOrId(dummyMap(dummies)(injected)) ) + taskToNode( getOrId(dummyMap(dummies)) ) } 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 Pure(eval, _) => uniform(Nil)( _ => Right(eval()) ) + case m: Mapped[t, k] => toNode[t,k](m.in)( right ∙ m.f )( m.alist ) + case m: FlatMapped[t, k] => toNode[t,k](m.in)( left ∙ m.f )( m.alist ) + case DependsOn(in, deps) => uniform( existToAny(deps) )( const(Left(in)) ∙ all ) case Join(in, f) => uniform(in)(f) } def inline[T](t: Task[T]) = t.work match { @@ -56,18 +54,13 @@ object Transform } } - def uniform[T, D](tasks: Seq[Task[D]])(f: Seq[Result[D]] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] { - type Mixed = HNil - val mixedIn = KNil - type Uniform = D - val uniformIn = tasks - def work(mixed: Results[HNil], uniform: Seq[Result[Uniform]]) = f(uniform) - } - def toNode[T, In <: HList](in: Tasks[In])(f: Results[In] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] { - type Mixed = In - val mixedIn = in - type Uniform = Nothing - val uniformIn = Nil - def work(results: Results[In], units: Seq[Result[Uniform]]) = f(results) + def uniform[T, D](tasks: Seq[Task[D]])(f: Seq[Result[D]] => Either[Task[T], T]): Node[Task, T] = + toNode[T, ({ type l[L[x]] = List[L[D]] })#l]( tasks.toList )( f )( AList.seq[D] ) + + def toNode[T, k[L[x]]](inputs: k[Task])(f: k[Result] => Either[Task[T], T])(implicit a: AList[k]): Node[Task, T] = new Node[Task, T] { + type K[L[x]] = k[L] + val in = inputs + val alist = a + def work(results: K[Result]) = f(results) } } \ No newline at end of file diff --git a/tasks/standard/TaskExtra.scala b/tasks/standard/TaskExtra.scala index 7ae8004b4..9df354ad5 100644 --- a/tasks/standard/TaskExtra.scala +++ b/tasks/standard/TaskExtra.scala @@ -8,15 +8,16 @@ package std import Task._ import java.io.{BufferedInputStream, BufferedReader, File, InputStream} -sealed trait MultiInTask[In <: HList] +sealed trait MultiInTask[K[L[x]]] { - def flatMap[T](f: In => Task[T]): Task[T] - def flatMapR[T](f: Results[In] => Task[T]): Task[T] - def map[T](f: In => T): Task[T] - def mapR[T](f: Results[In] => T): Task[T] + def flatMap[T](f: K[Id] => Task[T]): Task[T] + def flatMapR[T](f: K[Result] => Task[T]): Task[T] + def map[T](f: K[Id] => T): Task[T] + def mapR[T](f: K[Result] => T): Task[T] def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T] def mapFailure[T](f: Seq[Incomplete] => T): Task[T] } + sealed trait SingleInTask[S] { def flatMapR[T](f: Result[S] => Task[T]): Task[T] @@ -77,49 +78,45 @@ trait TaskExtra final def nop: Task[Unit] = constant( () ) final def constant[T](t: T): Task[T] = task(t) - final implicit def t2ToMulti[A,B](t: (Task[A],Task[B])) = multInputTask(t._1 :^: t._2 :^: KNil) - final implicit def f2ToHfun[A,B,R](f: (A,B) => R): (A :+: B :+: HNil => R) = { case a :+: b :+: HNil => f(a,b) } - - final implicit def t3ToMulti[A,B,C](t: (Task[A],Task[B],Task[C])) = multInputTask(t._1 :^: t._2 :^: t._3 :^: KNil) - final implicit def f3ToHfun[A,B,C,R](f: (A,B,C) => R): (A :+: B :+: C :+: HNil => R) = { case a :+: b :+: c :+: HNil => f(a,b,c) } - 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, 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 upcastTask[A >: B, B](t: Task[B]): Task[A] = t map { x => x : A } final implicit def toTasks[S](in: Seq[() => S]): Seq[Task[S]] = in.map(toTask) final implicit def iterableTask[S](in: Seq[S]): ForkTask[S, Seq] = new ForkTask[S, Seq] { def fork[T](f: S => T): Seq[Task[T]] = in.map(x => task(f(x))) def tasks: Seq[Task[S]] = fork(idFun) } - final implicit def joinAnyTasks(in: Seq[Task[_]]): JoinTask[Any, Seq] = joinTasks[Any](in map (x => x: Task[Any])) + import TaskExtra.{allM, anyFailM, existToAny, failM, successM} + + final implicit def joinAnyTasks(in: Seq[Task[_]]): JoinTask[Any, Seq] = joinTasks[Any]( existToAny(in) ) final implicit def joinTasks[S](in: Seq[Task[S]]): JoinTask[S, Seq] = new JoinTask[S, Seq] { def join: Task[Seq[S]] = new Join(in, (s: Seq[Result[S]]) => Right(TaskExtra.all(s)) ) def reduced(f: (S,S) => S): Task[S] = TaskExtra.reduced(in.toIndexedSeq, f) } - - import TaskExtra.{allM, anyFailM, failM, successM} - final implicit def multInputTask[In <: HList](tasks: Tasks[In]): MultiInTask[In] = new MultiInTask[In] { - def flatMapR[T](f: Results[In] => Task[T]): Task[T] = new FlatMapped(tasks, f) - def flatMap[T](f: In => Task[T]): Task[T] = flatMapR(f compose allM) - def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T] = flatMapR(f compose anyFailM) - def mapR[T](f: Results[In] => T): Task[T] = new Mapped(tasks, f) - def map[T](f: In => T): Task[T] = mapR(f compose allM) - def mapFailure[T](f: Seq[Incomplete] => T): Task[T] = mapR(f compose anyFailM) + final implicit def multT2Task[A,B](in: (Task[A], Task[B])) = multInputTask[({ type l[L[x]] = (L[A], L[B]) })#l](in)(AList.tuple2[A,B]) + + final implicit def multInputTask[K[L[X]]](tasks: K[Task])(implicit a: AList[K]): MultiInTask[K] = new MultiInTask[K] { + def flatMapR[T](f: K[Result] => Task[T]): Task[T] = new FlatMapped[T,K](tasks, f, a) + def flatMap[T](f: K[Id] => Task[T]): Task[T] = new FlatMapped[T, K](tasks, f compose allM, a) + def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T] = new FlatMapped[T,K](tasks, f compose anyFailM, a) + + def mapR[T](f: K[Result] => T): Task[T] = new Mapped[T,K](tasks, f, a) + def map[T](f: K[Id] => T): Task[T] = new Mapped[T,K](tasks, f compose allM, a) + def mapFailure[T](f: Seq[Incomplete] => T): Task[T] = new Mapped[T,K](tasks, f compose anyFailM, a) } final implicit def singleInputTask[S](in: Task[S]): SingleInTask[S] = new SingleInTask[S] { - type HL = S :+: HNil - private val ml = in :^: KNil - private def headM = (_: Results[HL]).combine.head + type K[L[x]] = L[S] + private def ml = AList.single[S] - def flatMapR[T](f: Result[S] => Task[T]): Task[T] = new FlatMapped[T, HL](ml, f ∙ headM) - def mapR[T](f: Result[S] => T): Task[T] = new Mapped[T, HL](ml, f ∙ headM) + def flatMapR[T](f: Result[S] => Task[T]): Task[T] = new FlatMapped[T, K](in, f, ml) + def mapR[T](f: Result[S] => T): Task[T] = new Mapped[T, K](in, f, ml) def dependsOn(tasks: Task[_]*): Task[S] = new DependsOn(in, tasks) def flatMap[T](f: S => Task[T]): Task[T] = flatMapR(f compose successM) @@ -198,12 +195,13 @@ object TaskExtra extends TaskExtra val (a, b) = i.splitAt(i.size / 2) reducePair( reduced(a, f), reduced(b, f), f ) } - def reducePair[S](a: Task[S], b: Task[S], f: (S, S) => S): Task[S] = - (a :^: b :^: KNil) map { case x :+: y :+: HNil => f(x,y) } - def anyFailM[In <: HList]: Results[In] => Seq[Incomplete] = in => + def reducePair[S](a: Task[S], b: Task[S], f: (S, S) => S): Task[S] = + multInputTask[({ type l[L[x]] = (L[S], L[S])})#l]((a,b))(AList.tuple2[S,S]) map f.tupled + + def anyFailM[K[L[x]]](implicit a: AList[K]): K[Result] => Seq[Incomplete] = in => { - val incs = failuresM(in) + val incs = failuresM(a)(in) if(incs.isEmpty) expectedFailure else incs } def failM[T]: Result[T] => Incomplete = { case Inc(i) => i; case x => expectedFailure } @@ -211,12 +209,12 @@ object TaskExtra extends TaskExtra def expectedFailure = throw Incomplete(None, message = Some("Expected dependency to fail.")) def successM[T]: Result[T] => T = { case Inc(i) => throw i; case Value(t) => t } - def allM[In <: HList]: Results[In] => In = in => + def allM[K[L[x]]](implicit a: AList[K]): K[Result] => K[Id] = in => { - val incs = failuresM(in) - if(incs.isEmpty) in.down(Result.tryValue) else throw incompleteDeps(incs) + val incs = failuresM(a)(in) + if(incs.isEmpty) a.transform(in, Result.tryValue) else throw incompleteDeps(incs) } - def failuresM[In <: HList]: Results[In] => Seq[Incomplete] = x => failures[Any](x.toList) + def failuresM[K[L[x]]](implicit a: AList[K]): K[Result] => Seq[Incomplete] = x => failures[Any](a.toList(x)) def all[D](in: Seq[Result[D]]) = { @@ -226,4 +224,6 @@ object TaskExtra extends TaskExtra def failures[A](results: Seq[Result[A]]): Seq[Incomplete] = results.collect { case Inc(i) => i } def incompleteDeps(incs: Seq[Incomplete]): Incomplete = Incomplete(None, causes = incs) + + private[sbt] def existToAny(in: Seq[Task[_]]): Seq[Task[Any]] = in.asInstanceOf[Seq[Task[Any]]] } diff --git a/tasks/src/test/scala/Execute.scala b/tasks/standard/src/test/scala/Execute.scala similarity index 75% rename from tasks/src/test/scala/Execute.scala rename to tasks/standard/src/test/scala/Execute.scala index 891ed4352..e4e68a1e9 100644 --- a/tasks/src/test/scala/Execute.scala +++ b/tasks/standard/src/test/scala/Execute.scala @@ -13,13 +13,13 @@ object ExecuteSpec extends Properties("Execute") val iGen = Arbitrary.arbInt.arbitrary property("evaluates simple task") = forAll(iGen, MaxWorkersGen) { (i: Int, workers: Int) => ("Workers: " + workers) |: - checkResult(tryRun(pure(i), false, workers), i) + checkResult(tryRun(task(i), false, workers), i) } // no direct dependencies currently /*property("evaluates simple static graph") = forAll(iGen, MaxWorkersGen) { (i: Int, workers: Int) => ("Workers: " + workers) |: { - def result = tryRun(Task(i) dependsOn(pure(false),pure("a")), false, workers) + def result = tryRun(Task(i) dependsOn(task(false),task("a")), false, workers) checkResult(result, i) } }*/ @@ -27,23 +27,23 @@ object ExecuteSpec extends Properties("Execute") property("evaluates simple mapped task") = forAll(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) => ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: { - def result = tryRun(pure(i).map(_*times), false, workers) + def result = tryRun(task(i).map(_*times), false, workers) checkResult(result, i*times) } } property("evaluates chained mapped task") = forAllNoShrink(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) => ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: { - val initial = pure(0) map(identity[Int]) - def task = ( initial /: (0 until times) )( (t,ignore) => t.map(_ + i)) - checkResult(tryRun(task, false, workers), i*times) + val initial = task(0) map(identity[Int]) + def t = ( initial /: (0 until times) )( (t,ignore) => t.map(_ + i)) + checkResult(tryRun(t, false, workers), i*times) } } property("evaluates simple bind") = forAll(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) => ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: { - def result = tryRun(pure(i).flatMap(x => pure(x*times)), false, workers) + def result = tryRun(task(i).flatMap(x => task(x*times)), false, workers) checkResult(result, i*times) } } diff --git a/tasks/standard/src/test/scala/TaskGen.scala b/tasks/standard/src/test/scala/TaskGen.scala new file mode 100644 index 000000000..5dd1529a9 --- /dev/null +++ b/tasks/standard/src/test/scala/TaskGen.scala @@ -0,0 +1,33 @@ +/* sbt -- Simple Build Tool + * Copyright 2009 Mark Harrah + */ +package sbt + +import org.scalacheck._ +import Gen.choose + +object TaskGen extends std.TaskExtra +{ + // upper bounds to make the tests finish in reasonable time + val MaxTasks = 100 + val MaxWorkers = 29 + val MaxJoin = 20 + + val MaxTasksGen = choose(0, MaxTasks) + val MaxWorkersGen = choose(1, MaxWorkers) + val MaxJoinGen = choose(0, MaxJoin) + val TaskListGen = MaxTasksGen.flatMap(size => Gen.listOfN(size, Arbitrary.arbInt.arbitrary)) + + def run[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): Result[T] = + { + val (service, shutdown) = CompletionService[Task[_], Completed](maxWorkers) + val dummies = std.Transform.DummyTaskMap(Nil) + val x = new Execute[Task](checkCycles, Execute.noTriggers)(std.Transform(dummies)) + try { x.run(root)(service) } finally { shutdown() } + } + def tryRun[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): T = + run(root, checkCycles, maxWorkers) match { + case Value(v) => v + case Inc(i) => throw i + } +} \ No newline at end of file diff --git a/tasks/src/test/scala/TaskRunnerCircular.scala b/tasks/standard/src/test/scala/TaskRunnerCircular.scala similarity index 73% rename from tasks/src/test/scala/TaskRunnerCircular.scala rename to tasks/standard/src/test/scala/TaskRunnerCircular.scala index c58b10616..7a3df0bbf 100644 --- a/tasks/src/test/scala/TaskRunnerCircular.scala +++ b/tasks/standard/src/test/scala/TaskRunnerCircular.scala @@ -11,26 +11,26 @@ object TaskRunnerCircularTest extends Properties("TaskRunner Circular") property("Allows references to completed tasks") = forAllNoShrink(MaxTasksGen, MaxWorkersGen) { allowedReference _ } final def allowedReference(intermediate: Int, workers: Int) = { - val top = pure("top", intermediate) - def iterate(task: Task[Int]): Task[Int] = - task flatMap { t => + val top = task(intermediate).named("top") + def iterate(tk: Task[Int]): Task[Int] = + tk flatMap { t => if(t <= 0) top else - iterate(pure((t-1).toString, t-1) ) + iterate(task(t-1).named((t-1).toString) ) } try { checkResult(tryRun(iterate(top), true, workers), intermediate) } catch { case i: Incomplete if cyclic(i) => ("Unexpected cyclic exception: " + i) |: false } } final def checkCircularReferences(intermediate: Int, workers: Int) = { - lazy val top = iterate(pure("bottom", intermediate), intermediate) - def iterate(task: Task[Int], i: Int): Task[Int] = - task flatMap { t => + lazy val top = iterate(task(intermediate).named("bottom"), intermediate) + def iterate(tk: Task[Int], i: Int): Task[Int] = + tk flatMap { t => if(t <= 0) top else - iterate(pure((t-1).toString, t-1), i-1) + iterate(task(t-1).named((t-1).toString), i-1) } try { tryRun(top, true, workers); false } catch { case i: Incomplete => cyclic(i) } diff --git a/tasks/src/test/scala/TaskRunnerFork.scala b/tasks/standard/src/test/scala/TaskRunnerFork.scala similarity index 87% rename from tasks/src/test/scala/TaskRunnerFork.scala rename to tasks/standard/src/test/scala/TaskRunnerFork.scala index 646d7eed6..63961aee5 100644 --- a/tasks/src/test/scala/TaskRunnerFork.scala +++ b/tasks/standard/src/test/scala/TaskRunnerFork.scala @@ -25,13 +25,13 @@ object TaskRunnerForkTest extends Properties("TaskRunner Fork") } def runDoubleJoin(a: Int, b: Int, workers: Int) { - def inner(i: Int) = List.range(0, b).map(j => pure(j.toString, j)).join + def inner(i: Int) = List.range(0, b).map(j => task(j).named(j.toString)).join tryRun( List.range(0,a).map(inner).join, false, workers) } property("fork and reduce") = forAll(TaskListGen, MaxWorkersGen) { (m: List[Int], workers: Int) => (!m.isEmpty) ==> { val expected = m.reduceLeft(_+_) - checkResult(tryRun( m.reduced(_ + _), false, workers), expected) + checkResult(tryRun( m.tasks.reduced(_ + _), false, workers), expected) } } } diff --git a/tasks/standard/src/test/scala/Test.scala b/tasks/standard/src/test/scala/Test.scala new file mode 100644 index 000000000..8827bcf91 --- /dev/null +++ b/tasks/standard/src/test/scala/Test.scala @@ -0,0 +1,60 @@ +/* sbt -- Simple Build Tool + * Copyright 2010 Mark Harrah + */ +package sbt + +import Types._ +import Task._ +import Execute._ + +object Test extends std.TaskExtra +{ + def t2[A, B](a: Task[A], b: Task[B]) = multInputTask[({type l[L[x]] = (L[A], L[B])})#l]((a, b))(AList.tuple2) + def t3[A, B, C](a: Task[A], b: Task[B], c: Task[C]) = multInputTask[({type l[L[x]] = (L[A], L[B], L[C])})#l]((a, b, c))(AList.tuple3) + + val a = task(3) + val b = task[Boolean](error("test")) + val b2 = task(true) + val c = task("asdf") + + val h1 = t3(a,b,c).map { case (aa,bb,cc) => aa + " " + bb + " " + cc } + val h2 = t3(a,b2,c).map { case (aa,bb,cc) => aa + " " + bb + " " + cc } + + type Values = (Result[Int], Result[Boolean], Result[String]) + + val f: Values => Any = { + case (Value(aa), Value(bb), Value(cc)) => aa + " " + bb + " " + cc + case x => + val cs = x.productIterator.toList.collect { case Inc(x) => x } // workaround for double definition bug + throw Incomplete(None, causes = cs) + } + val d2 = t3(a,b2,c) mapR f + val f2: Values => Task[Any] = { + case (Value(aa), Value(bb), Value(cc)) => task(aa + " " + bb + " " + cc) + case x => d3 + } + lazy val d = t3(a,b,c) flatMapR f2 + val f3: Values => Task[Any] = { + case (Value(aa), Value(bb), Value(cc)) => task(aa + " " + bb + " " + cc) + case x => d2 + } + lazy val d3= t3(a,b,c) flatMapR f3 + + def d4(i: Int): Task[Int] = nop flatMap { _ => val x = math.random; if(x < 0.01) task(i); else d4(i+1) } + + def go() + { + def run[T](root: Task[T]) = + println("Result : " + TaskGen.run(root, true, 2)) + + run(a) + run(b) + run(b2) + run(c) + run(d) + run(d2) + run( d4(0) ) + run(h1) + run(h2) + } +} \ No newline at end of file diff --git a/tasks/src/test/scala/TestRunnerCall.scala b/tasks/standard/src/test/scala/TestRunnerCall.scala similarity index 91% rename from tasks/src/test/scala/TestRunnerCall.scala rename to tasks/standard/src/test/scala/TestRunnerCall.scala index 6b1ea6fcc..f8509e782 100644 --- a/tasks/src/test/scala/TestRunnerCall.scala +++ b/tasks/standard/src/test/scala/TestRunnerCall.scala @@ -24,11 +24,11 @@ object TaskRunnerCallTest extends Properties("TaskRunner Call") (index, x1, x2) => { if(index == i) - pure(x2) + task(x2) else iterate( (index+1, x2, x1+x2) ) } - def iterate(iteration: (Int,Int,Int)) = pure( iteration ) flatMap next.tupled + def iterate(iteration: (Int,Int,Int)) = task( iteration ) flatMap next.tupled iterate( (1, 0, 1) ) } final def fibDirect(i: Int): Int = diff --git a/tasks/src/test/scala/TestRunnerSort.scala b/tasks/standard/src/test/scala/TestRunnerSort.scala similarity index 87% rename from tasks/src/test/scala/TestRunnerSort.scala rename to tasks/standard/src/test/scala/TestRunnerSort.scala index 80a8c3cd2..0ad82970a 100644 --- a/tasks/src/test/scala/TestRunnerSort.scala +++ b/tasks/standard/src/test/scala/TestRunnerSort.scala @@ -35,14 +35,14 @@ object TaskRunnerSortTest extends Properties("TaskRunnerSort") final def sort(a: Seq[Int]): Task[Seq[Int]] = { if(a.length < 200) - pure(sortDirect(a)) + task(sortDirect(a)) else { - pure(a) flatMap { a => + task(a) flatMap { a => val pivot = a(0) val (lt,gte) = a.view.drop(1).partition(_ < pivot) - sort(lt) :^: sort(gte) :^: KNil mapH { - case l :+: g :+: HNil => l ++ List(pivot) ++ g + Test.t2(sort(lt), sort(gte)) map { + case (l, g) => l ++ List(pivot) ++ g } } } diff --git a/tasks/src/test/scala/checkResult.scala b/tasks/standard/src/test/scala/checkResult.scala similarity index 100% rename from tasks/src/test/scala/checkResult.scala rename to tasks/standard/src/test/scala/checkResult.scala diff --git a/util/collection/AList.scala b/util/collection/AList.scala new file mode 100644 index 000000000..212a58411 --- /dev/null +++ b/util/collection/AList.scala @@ -0,0 +1,211 @@ +package sbt + + import Classes.Applicative + import Types._ + +/** An abstraction over (* -> *) -> * with the purpose of abstracting over arity abstractions like KList and TupleN +* as well as homogeneous sequences Seq[M[T]]. */ +trait AList[K[L[x]] ] +{ + def transform[M[_], N[_]](value: K[M], f: M ~> N): K[N] + def traverse[M[_], N[_], P[_]](value: K[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[K[P]] + def foldr[M[_], A](value: K[M], f: (M[_], A) => A, init: A): A + + def toList[M[_]](value: K[M]): List[M[_]] = foldr[M, List[M[_]]](value, _ :: _, Nil) + def apply[M[_], C](value: K[M], f: K[Id] => C)(implicit a: Applicative[M]): M[C] = + a.map(f, traverse[M, M, Id](value, idK[M])(a)) +} +object AList +{ + type Empty = AList[({ type l[L[x]] = Unit})#l] + val empty: Empty = new Empty { + def transform[M[_], N[_]](in: Unit, f: M ~> N) = () + def foldr[M[_], T](in: Unit, f: (M[_], T) => T, init: T) = init + override def apply[M[_], C](in: Unit, f: Unit => C)(implicit app: Applicative[M]): M[C] = app.pure( f( () ) ) + def traverse[M[_], N[_], P[_]](in: Unit, f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[Unit] = np.pure( () ) + } + + type SeqList[T] = AList[({ type l[L[x]] = List[L[T]] })#l] + def seq[T]: SeqList[T] = new SeqList[T] + { + def transform[M[_], N[_]](s: List[M[T]], f: M ~> N) = s.map(f.fn[T]) + def foldr[M[_], A](s: List[M[T]], f: (M[_], A) => A, init: A): A = (init /: s.reverse)( (t, m) => f(m,t)) + override def apply[M[_], C](s: List[M[T]], f: List[T] => C)(implicit ap: Applicative[M]): M[C] = + { + def loop[V](in: List[M[T]], g: List[T] => V): M[V] = + in match { + case Nil => ap.pure(g(Nil)) + case x :: xs => + val h = (ts: List[T]) => (t: T) => g(t :: ts) + ap.apply( loop(xs, h), x ) + } + loop(s, f) + } + def traverse[M[_], N[_], P[_]](s: List[M[T]], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[List[P[T]]] = ??? + } + + def klist[KL[M[_]] <: KList[M] { type Transform[N[_]] = KL[N] }]: AList[KL] = new AList[KL] { + def transform[M[_], N[_]](k: KL[M], f: M ~> N) = k.transform(f) + def foldr[M[_], T](k: KL[M], f: (M[_], T) => T, init: T): T = k.foldr(f, init) + override def apply[M[_], C](k: KL[M], f: KL[Id] => C)(implicit app: Applicative[M]): M[C] = k.apply(f)(app) + def traverse[M[_], N[_], P[_]](k: KL[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[KL[P]] = k.traverse[N,P](f)(np) + } + + type Single[A] = AList[({ type l[L[x]] = L[A]})#l] + def single[A]: Single[A] = new Single[A] { + def transform[M[_], N[_]](a: M[A], f: M ~> N) = f(a) + def foldr[M[_], T](a: M[A], f: (M[_], T) => T, init: T): T = f(a, init) + def traverse[M[_], N[_], P[_]](a: M[A], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[P[A]] = f(a) + } + + + type ASplit[K[L[x]], B[x]] = AList[ ({ type l[L[x]] = K[ (L ∙ B)#l] })#l ] + def asplit[ K[L[x]], B[x] ](base: AList[K]): ASplit[K,B] = new ASplit[K, B] + { + type Split[ L[x] ] = K[ (L ∙ B)#l ] + def transform[M[_], N[_]](value: Split[M], f: M ~> N): Split[N] = + base.transform[(M ∙ B)#l, (N ∙ B)#l](value, nestCon[M,N,B](f)) + + def traverse[M[_], N[_], P[_]](value: Split[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[Split[P]] = + { + val g = nestCon[M, (N ∙ P)#l, B](f) + base.traverse[(M ∙ B)#l, N, (P ∙ B)#l](value, g)(np) + } + + def foldr[M[_], A](value: Split[M], f: (M[_], A) => A, init: A): A = + base.foldr[(M ∙ B)#l, A](value, f, init) + } + + // TODO: auto-generate + sealed trait T2K[A,B] { type l[L[x]] = (L[A], L[B]) } + type T2List[A,B] = AList[T2K[A,B]#l] + def tuple2[A, B]: T2List[A,B] = new T2List[A,B] + { + type T2[M[_]] = (M[A], M[B]) + def transform[M[_], N[_]](t: T2[M], f: M ~> N): T2[N] = (f(t._1), f(t._2)) + def foldr[M[_], T](t: T2[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, init)) + def traverse[M[_], N[_], P[_]](t: T2[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[T2[P]] = + { + val g = (Tuple2.apply[P[A], P[B]] _).curried + np.apply( np.map(g, f(t._1)), f(t._2) ) + } + } + + sealed trait T3K[A,B,C] { type l[L[x]] = (L[A], L[B], L[C]) } + type T3List[A,B,C] = AList[T3K[A,B,C]#l] + def tuple3[A, B, C]: T3List[A,B,C] = new T3List[A,B,C] + { + type T3[M[_]] = (M[A], M[B], M[C]) + def transform[M[_], N[_]](t: T3[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3)) + def foldr[M[_], T](t: T3[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, init))) + def traverse[M[_], N[_], P[_]](t: T3[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[T3[P]] = + { + val g = (Tuple3.apply[P[A],P[B],P[C]] _).curried + np.apply( np.apply( np.map(g, f(t._1)), f(t._2) ), f(t._3) ) + } + } + + sealed trait T4K[A,B,C,D] { type l[L[x]] = (L[A], L[B], L[C], L[D]) } + type T4List[A,B,C,D] = AList[T4K[A,B,C,D]#l] + def tuple4[A, B, C, D]: T4List[A,B,C,D] = new T4List[A,B,C,D] + { + type T4[M[_]] = (M[A], M[B], M[C], M[D]) + def transform[M[_], N[_]](t: T4[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4)) + def foldr[M[_], T](t: T4[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, init)))) + def traverse[M[_], N[_], P[_]](t: T4[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[T4[P]] = + { + val g = (Tuple4.apply[P[A], P[B], P[C], P[D]] _).curried + np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)) + } + } + + sealed trait T5K[A,B,C,D,E] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E]) } + type T5List[A,B,C,D,E] = AList[T5K[A,B,C,D,E]#l] + def tuple5[A, B, C, D, E]: T5List[A,B,C,D,E] = new T5List[A,B,C,D,E] { + type T5[M[_]] = (M[A], M[B], M[C], M[D], M[E]) + def transform[M[_], N[_]](t: T5[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5)) + def foldr[M[_], T](t: T5[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, init))))) + def traverse[M[_], N[_], P[_]](t: T5[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[T5[P]] = + { + val g = (Tuple5.apply[P[A],P[B],P[C],P[D],P[E]] _ ).curried + np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5) ) + } + } + + sealed trait T6K[A,B,C,D,E,F] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F]) } + type T6List[A,B,C,D,E,F] = AList[T6K[A,B,C,D,E,F]#l] + def tuple6[A, B, C, D, E, F]: T6List[A,B,C,D,E,F] = new T6List[A,B,C,D,E,F] { + type T6[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F]) + def transform[M[_], N[_]](t: T6[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6)) + def foldr[M[_], T](t: T6[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, init)))))) + def traverse[M[_], N[_], P[_]](t: T6[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[T6[P]] = + { + val g = (Tuple6.apply[P[A],P[B],P[C],P[D],P[E],P[F]] _ ).curried + np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)) + } + } + + sealed trait T7K[A,B,C,D,E,F,G] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F], L[G]) } + type T7List[A,B,C,D,E,F,G] = AList[T7K[A,B,C,D,E,F,G]#l] + def tuple7[A,B,C,D,E,F,G]: T7List[A,B,C,D,E,F,G] = new T7List[A,B,C,D,E,F,G] { + type T7[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G]) + def transform[M[_], N[_]](t: T7[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6), f(t._7)) + def foldr[M[_], T](t: T7[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, f(t._7, init))))))) + def traverse[M[_], N[_], P[_]](t: T7[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[T7[P]] = + { + val g = (Tuple7.apply[P[A],P[B],P[C],P[D],P[E],P[F],P[G]] _ ).curried + np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)), f(t._7)) + } + } + sealed trait T8K[A,B,C,D,E,F,G,H] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F], L[G], L[H]) } + type T8List[A,B,C,D,E,F,G,H] = AList[T8K[A,B,C,D,E,F,G,H]#l] + def tuple8[A,B,C,D,E,F,G,H]: T8List[A,B,C,D,E,F,G,H] = new T8List[A,B,C,D,E,F,G,H] { + type T8[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H]) + def transform[M[_], N[_]](t: T8[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6), f(t._7), f(t._8)) + def foldr[M[_], T](t: T8[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, f(t._7, f(t._8, init)))))))) + def traverse[M[_], N[_], P[_]](t: T8[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[T8[P]] = + { + val g = (Tuple8.apply[P[A],P[B],P[C],P[D],P[E],P[F],P[G],P[H]] _ ).curried + np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)), f(t._7)), f(t._8)) + } + } + + sealed trait T9K[A,B,C,D,E,F,G,H,I] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F], L[G], L[H], L[I]) } + type T9List[A,B,C,D,E,F,G,H,I] = AList[T9K[A,B,C,D,E,F,G,H,I]#l] + def tuple9[A,B,C,D,E,F,G,H,I]: T9List[A,B,C,D,E,F,G,H,I] = new T9List[A,B,C,D,E,F,G,H,I] { + type T9[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I]) + def transform[M[_], N[_]](t: T9[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6), f(t._7), f(t._8), f(t._9)) + def foldr[M[_], T](t: T9[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, f(t._7, f(t._8, f(t._9, init))))))))) + def traverse[M[_], N[_], P[_]](t: T9[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[T9[P]] = + { + val g = (Tuple9.apply[P[A],P[B],P[C],P[D],P[E],P[F],P[G],P[H],P[I]] _ ).curried + np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)), f(t._7)), f(t._8)), f(t._9)) + } + } + + sealed trait T10K[A,B,C,D,E,F,G,H,I,J] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F], L[G], L[H], L[I], L[J]) } + type T10List[A,B,C,D,E,F,G,H,I,J] = AList[T10K[A,B,C,D,E,F,G,H,I,J]#l] + def tuple10[A,B,C,D,E,F,G,H,I,J]: T10List[A,B,C,D,E,F,G,H,I,J] = new T10List[A,B,C,D,E,F,G,H,I,J] { + type T10[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J]) + def transform[M[_], N[_]](t: T10[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6), f(t._7), f(t._8), f(t._9), f(t._10)) + def foldr[M[_], T](t: T10[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, f(t._7, f(t._8, f(t._9, f(t._10, init)))))))))) + def traverse[M[_], N[_], P[_]](t: T10[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[T10[P]] = + { + val g = (Tuple10.apply[P[A],P[B],P[C],P[D],P[E],P[F],P[G],P[H],P[I],P[J]] _ ).curried + np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)), f(t._7)), f(t._8)), f(t._9)), f(t._10)) + } + } + + sealed trait T11K[A,B,C,D,E,F,G,H,I,J,K] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F], L[G], L[H], L[I], L[J], L[K]) } + type T11List[A,B,C,D,E,F,G,H,I,J,K] = AList[T11K[A,B,C,D,E,F,G,H,I,J,K]#l] + def tuple11[A,B,C,D,E,F,G,H,I,J,K]: T11List[A,B,C,D,E,F,G,H,I,J,K] = new T11List[A,B,C,D,E,F,G,H,I,J,K] { + type T11[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K]) + def transform[M[_], N[_]](t: T11[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6), f(t._7), f(t._8), f(t._9), f(t._10), f(t._11)) + def foldr[M[_], T](t: T11[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, f(t._7, f(t._8, f(t._9, f(t._10, f(t._11,init))))))))))) + def traverse[M[_], N[_], P[_]](t: T11[M], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[T11[P]] = + { + val g = (Tuple11.apply[P[A],P[B],P[C],P[D],P[E],P[F],P[G],P[H],P[I],P[J],P[K]] _ ).curried + np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)), f(t._7)), f(t._8)), f(t._9)), f(t._10)), f(t._11)) + } + } +} diff --git a/util/collection/Classes.scala b/util/collection/Classes.scala new file mode 100644 index 000000000..74796c829 --- /dev/null +++ b/util/collection/Classes.scala @@ -0,0 +1,27 @@ +package sbt + +object Classes +{ + trait Applicative[M[_]] + { + def apply[S,T](f: M[S => T], v: M[S]): M[T] + def pure[S](s: => S): M[S] + def map[S, T](f: S => T, v: M[S]): M[T] + } + trait Monad[M[_]] extends Applicative[M] + { + def flatten[T](m: M[M[T]]): M[T] + } + implicit val optionMonad: Monad[Option] = new Monad[Option] { + def apply[S,T](f: Option[S => T], v: Option[S]) = (f, v) match { case (Some(fv), Some(vv)) => Some(fv(vv)); case _ => None } + def pure[S](s: => S) = Some(s) + def map[S, T](f: S => T, v: Option[S]) = v map f + def flatten[T](m: Option[Option[T]]): Option[T] = m.flatten + } + implicit val listMonad: Monad[List] = new Monad[List] { + def apply[S,T](f: List[S => T], v: List[S]) = for(fv <- f; vv <- v) yield fv(vv) + def pure[S](s: => S) = s :: Nil + def map[S, T](f: S => T, v: List[S]) = v map f + def flatten[T](m: List[List[T]]): List[T] = m.flatten + } +} \ No newline at end of file diff --git a/util/collection/INode.scala b/util/collection/INode.scala index 0e48324e3..1ac9152a2 100644 --- a/util/collection/INode.scala +++ b/util/collection/INode.scala @@ -3,7 +3,7 @@ package sbt import java.lang.Runnable import java.util.concurrent.{atomic, Executor, LinkedBlockingQueue} import atomic.{AtomicBoolean, AtomicInteger} - import Types.{:+:, Id} + import Types.{:+:, ConstK, Id} object EvaluationState extends Enumeration { val New, Blocked, Ready, Calling, Evaluated = Value @@ -24,8 +24,7 @@ abstract class EvaluateSettings[Scope] private[this] val transform: Initialize ~> INode = new (Initialize ~> INode) { def apply[T](i: Initialize[T]): INode[T] = i match { case k: Keyed[s, T] => single(getStatic(k.scopedKey), k.transform) - case a: Apply[hl,T] => new MixedNode(a.inputs transform transform, a.f) - case u: Uniform[s, T] => new UniformNode(u.inputs map transform.fn[s], u.f) + 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 o: Optional[s,T] => o.a match { @@ -155,8 +154,9 @@ abstract class EvaluateSettings[Scope] protected def dependsOn: Seq[INode[_]] protected def evaluate0(): Unit } - private[this] def constant[T](f: () => T): INode[T] = new MixedNode[HNil, T](KNil, _ => f()) - private[this] def single[S,T](in: INode[S], f: S => T): INode[T] = new MixedNode[S :+: HNil, T](in :^: KNil, hl => f(hl.head)) + + private[this] def constant[T](f: () => T): INode[T] = new MixedNode[ConstK[Unit]#l, T]((), _ => f(), AList.empty) + private[this] def single[S,T](in: INode[S], f: S => T): INode[T] = new MixedNode[ ({ type l[L[x]] = L[S] })#l, T](in, f, AList.single[S]) private[this] final class BindNode[S,T](in: INode[S], f: S => INode[T]) extends INode[T] { protected def dependsOn = in :: Nil @@ -166,14 +166,9 @@ abstract class EvaluateSettings[Scope] setValue(value) } } - private[this] final class UniformNode[S,T](in: Seq[INode[S]], f: Seq[S] => T) extends INode[T] + private[this] final class MixedNode[K[L[x]], T](in: K[INode], f: K[Id] => T, alist: AList[K]) extends INode[T] { - protected def dependsOn = in - protected def evaluate0(): Unit = setValue( f(in.map(_.get)) ) - } - private[this] final class MixedNode[HL <: HList, T](in: KList[INode, HL], f: HL => T) extends INode[T] - { - protected def dependsOn = in.toList - protected def evaluate0(): Unit = setValue( f( in down getValue ) ) + protected def dependsOn = alist.toList(in) + protected def evaluate0(): Unit = setValue( f( alist.transform(in, getValue) ) ) } } diff --git a/util/collection/KList.scala b/util/collection/KList.scala index 7b58aca32..70e3852f9 100644 --- a/util/collection/KList.scala +++ b/util/collection/KList.scala @@ -1,76 +1,49 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah - */ package sbt -import Types._ + import Types._ + import Classes.Applicative -/** A higher-order heterogeneous list. It has a type constructor M[_] and -* type parameters HL. The underlying data is M applied to each type parameter. -* Explicitly tracking M[_] allows performing natural transformations or ensuring -* all data conforms to some common type. -* -* For background, see -* http://apocalisp.wordpress.com/2010/11/01/type-level-programming-in-scala-part-8a-klist%C2%A0motivation/ - */ -sealed trait KList[+M[_], HL <: HList] +/** Heterogeneous list with each element having type M[T] for some type T.*/ +sealed trait KList[+M[_]] { - type Raw = HL - /** Transform to the underlying HList type.*/ - def down(implicit ev: M ~> Id): HL - /** Apply a natural transformation. */ - def transform[N[_]](f: M ~> N): KList[N, HL] - /** Convert to a List. */ + type Transform[N[_]] <: KList[N] + + /** Apply the natural transformation `f` to each element. */ + def transform[N[_]](f: M ~> N): Transform[N] + + def foldr[T](f: (M[_], T) => T, init: T): T = init // had trouble defining it in KNil + def apply[N[x] >: M[x], Z](f: Transform[Id] => Z)(implicit ap: Applicative[N]): N[Z] + def traverse[N[_], P[_]](f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[Transform[P]] def toList: List[M[_]] - /** Convert to an HList. */ - def combine[N[X] >: M[X]]: HL#Wrap[N] - - def foldr[P[_ <: HList],N[X] >: M[X]](f: KFold[N,P]): P[HL] } -trait KFold[M[_],P[_ <: HList]] +final case class KCons[H, +T <: KList[M], +M[_]](head: M[H], tail: T) extends KList[M] { - def kcons[H,T <: HList](h: M[H], acc: P[T]): P[H :+: T] - def knil: P[HNil] -} + final type Transform[N[_]] = KCons[H, tail.Transform[N], N] -final case class KCons[H, T <: HList, +M[_]](head: M[H], tail: KList[M,T]) extends KList[M, H :+: T] + def transform[N[_]](f: M ~> N) = KCons(f(head), tail.transform(f)) + def toList: List[M[_]] = head :: tail.toList + def apply[N[x] >: M[x], Z](f: Transform[Id] => Z)(implicit ap: Applicative[N]): N[Z] = + { + val g = (t: tail.Transform[Id]) => (h: H) =>f( KCons[H, tail.Transform[Id], Id](h, t) ) + ap.apply( tail.apply[N, H => Z](g), head ) + } + def traverse[N[_], P[_]](f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[Transform[P]] = + { + val tt: N[tail.Transform[P]] = tail.traverse[N,P](f) + val g = (t: tail.Transform[P]) => (h: P[H]) => KCons(h, t) + np.apply(np.map(g, tt), f(head)) + } + def :^:[A,N[x] >: M[x]](h: N[A]) = KCons(h, this) + override def foldr[T](f: (M[_], T) => T, init: T): T = f(head, tail.foldr(f, init)) +} +sealed abstract class KNil extends KList[Nothing] { - def down(implicit f: M ~> Id) = HCons(f(head), tail down f) - def transform[N[_]](f: M ~> N) = KCons( f(head), tail transform f ) - // prepend - def :^: [N[X] >: M[X], G](g: N[G]) = KCons(g, this) - def toList = head :: tail.toList - - def combine[N[X] >: M[X]]: (H :+: T)#Wrap[N] = HCons(head, tail.combine) - - override def toString = head + " :^: " + tail.toString - - def foldr[P[_ <: HList],N[X] >: M[X]](f: KFold[N,P]) = f.kcons(head, tail foldr f) + final type Transform[N[_]] = KNil + final def transform[N[_]](f: Nothing ~> N): Transform[N] = KNil + final def toList = Nil + final def apply[N[x], Z](f: KNil => Z)(implicit ap: Applicative[N]): N[Z] = ap.pure(f(KNil)) + final def traverse[N[_], P[_]](f: Nothing ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[KNil] = np.pure(KNil) } - -sealed class KNil extends KList[Nothing, HNil] -{ - def down(implicit f: Nothing ~> Id) = HNil - def transform[N[_]](f: Nothing ~> N) = KNil - def :^: [M[_], H](h: M[H]) = KCons(h, this) - def toList = Nil - def combine[N[X]] = HNil - override def foldr[P[_ <: HList],N[_]](f: KFold[N,P]) = f.knil - override def toString = "KNil" -} -object KNil extends KNil - -object KList -{ - // nicer alias for pattern matching - val :^: = KCons - - def fromList[M[_]](s: Seq[M[_]]): KList[M, _ <: HList] = if(s.isEmpty) KNil else KCons(s.head, fromList(s.tail)) - - // haven't found a way to convince scalac that KList[M, H :+: T] implies KCons[H,T,M] - // Therefore, this method exists to put the cast in one location. - implicit def kcons[H, T <: HList, M[_]](kl: KList[M, H :+: T]): KCons[H,T,M] = - kl.asInstanceOf[KCons[H,T,M]] - // haven't need this, but for symmetry with kcons: - implicit def knil[M[_]](kl: KList[M, HNil]): KNil = KNil +case object KNil extends KNil { + def :^:[M[_], H](h: M[H]): KCons[H, KNil, M] = KCons(h, this) } diff --git a/util/collection/Settings.scala b/util/collection/Settings.scala index 6df7291af..981096c0b 100644 --- a/util/collection/Settings.scala +++ b/util/collection/Settings.scala @@ -61,10 +61,12 @@ trait Init[Scope] def setting[T](key: ScopedKey[T], init: Initialize[T], pos: SourcePosition = NoPosition): Setting[T] = new Setting[T](key, init, pos) def value[T](value: => T): Initialize[T] = new Value(value _) def optional[T,U](i: Initialize[T])(f: Option[T] => U): Initialize[U] = new Optional(Some(i), f) - def update[T](key: ScopedKey[T])(f: T => T): Setting[T] = new Setting[T](key, app(key :^: KNil)(hl => f(hl.head)), NoPosition) + def update[T](key: ScopedKey[T])(f: T => T): Setting[T] = new Setting[T](key, map(key)(f), NoPosition) def bind[S,T](in: Initialize[S])(f: S => Initialize[T]): Initialize[T] = new Bind(f, in) - def app[HL <: HList, T](inputs: KList[Initialize, HL])(f: HL => T): Initialize[T] = new Apply(f, inputs) - def uniform[S,T](inputs: Seq[Initialize[S]])(f: Seq[S] => T): Initialize[T] = new Uniform(f, inputs) + def map[S,T](in: Initialize[S])(f: S => T): Initialize[T] = new Apply[ ({ type l[L[x]] = L[S] })#l, T](f, in, AList.single[S]) + def app[K[L[x]], T](inputs: K[Initialize])(f: K[Id] => T)(implicit alist: AList[K]): Initialize[T] = new Apply[K, T](f, inputs, alist) + def uniform[S,T](inputs: Seq[Initialize[S]])(f: Seq[S] => T): Initialize[T] = + new Apply[({ type l[L[x]] = List[L[S]] })#l, T](f, inputs.toList, AList.seq[S]) def empty(implicit delegates: Scope => Seq[Scope]): Settings[Scope] = new Settings0(Map.empty, delegates) def asTransform(s: Settings[Scope]): ScopedKey ~> Id = new (ScopedKey ~> Id) { @@ -219,11 +221,12 @@ trait Init[Scope] def apply[S](g: T => S): Initialize[S] def mapReferenced(g: MapScoped): Initialize[T] def validateReferenced(g: ValidateRef): ValidatedInit[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 Apply[T :+: S :+: HNil, U]( { case t :+: s :+: HNil => f(t,s)}, this :^: o :^: KNil) def mapConstant(g: MapConstant): Initialize[T] def evaluate(map: Settings[Scope]): T + def zip[S](o: Initialize[S]): Initialize[(T,S)] = zipTupled(o)(idFun) + def zipWith[S,U](o: Initialize[S])(f: (T,S) => U): Initialize[U] = zipTupled(o)(f.tupled) + private[this] def zipTupled[S,U](o: Initialize[S])(f: ((T,S)) => U): Initialize[U] = + new Apply[({ type l[L[x]] = (L[T], L[S]) })#l, U](f, (this, o), AList.tuple2[T,S]) } object Initialize { @@ -330,34 +333,21 @@ trait Init[Scope] def mapConstant(g: MapConstant) = this def evaluate(map: Settings[Scope]): T = value() } - private[sbt] final class Apply[HL <: HList, T](val f: HL => T, val inputs: KList[Initialize, HL]) extends Initialize[T] + private[sbt] final class Apply[K[L[x]], T](val f: K[Id] => T, val inputs: K[Initialize], val alist: AList[K]) extends Initialize[T] { - def dependencies = deps(inputs.toList) + def dependencies = deps(alist.toList(inputs)) def mapReferenced(g: MapScoped) = mapInputs( mapReferencedT(g) ) - def apply[S](g: T => S) = new Apply(g compose f, inputs) + def apply[S](g: T => S) = new Apply(g compose f, inputs, alist) def mapConstant(g: MapConstant) = mapInputs( mapConstantT(g) ) - def mapInputs(g: Initialize ~> Initialize): Initialize[T] = new Apply(f, inputs transform g) - def evaluate(ss: Settings[Scope]) = f(inputs down evaluateT(ss)) + def mapInputs(g: Initialize ~> Initialize): Initialize[T] = new Apply(f, alist.transform(inputs, g), alist) + def evaluate(ss: Settings[Scope]) = f(alist.transform(inputs, evaluateT(ss))) def validateReferenced(g: ValidateRef) = { - val tx = inputs transform validateReferencedT(g) - val undefs = tx.toList.flatMap(_.left.toSeq.flatten) + val tx = alist.transform(inputs, validateReferencedT(g)) + val undefs = alist.toList(tx).flatMap(_.left.toSeq.flatten) val get = new (ValidatedInit ~> Initialize) { def apply[T](vr: ValidatedInit[T]) = vr.right.get } - if(undefs.isEmpty) Right(new Apply(f, tx transform get)) else Left(undefs) + if(undefs.isEmpty) Right(new Apply(f, alist.transform(tx, get), alist)) else Left(undefs) } } - private[sbt] final class Uniform[S, T](val f: Seq[S] => T, val inputs: Seq[Initialize[S]]) extends Initialize[T] - { - def dependencies = deps(inputs) - def mapReferenced(g: MapScoped) = new Uniform(f, inputs map mapReferencedT(g).fn) - def validateReferenced(g: ValidateRef) = - { - val (undefs, ok) = Util.separateE(inputs map validateReferencedT(g).fn ) - if(undefs.isEmpty) Right( new Uniform(f, ok) ) else Left(undefs.flatten) - } - def apply[S](g: T => S) = new Uniform(g compose f, inputs) - def mapConstant(g: MapConstant) = new Uniform(f, inputs map mapConstantT(g).fn) - def evaluate(ss: Settings[Scope]) = f(inputs map evaluateT(ss).fn ) - } private def remove[T](s: Seq[T], v: T) = s filterNot (_ == v) } diff --git a/util/collection/TypeFunctions.scala b/util/collection/TypeFunctions.scala index bbfad9b8e..6a4978750 100644 --- a/util/collection/TypeFunctions.scala +++ b/util/collection/TypeFunctions.scala @@ -7,6 +7,7 @@ trait TypeFunctions { type Id[X] = X sealed trait Const[A] { type Apply[B] = A } + sealed trait ConstK[A] { type l[L[x]] = A } sealed trait Compose[A[_], B[_]] { type Apply[T] = A[B[T]] } sealed trait ∙[A[_], B[_]] { type l[T] = A[B[T]] } sealed trait P1of2[M[_,_], A] { type Apply[B] = M[A,B]; type Flip[B] = M[B, A] } @@ -16,6 +17,7 @@ trait TypeFunctions final val some = new (Id ~> Some) { def apply[T](t: T) = Some(t) } final def idFun[T] = (t: T) => t final def const[A,B](b: B): A=> B = _ => b + final def idK[M[_]]: M ~> M = new (M ~> M) { def apply[T](m: M[T]): M[T] = m } def nestCon[M[_], N[_], G[_]](f: M ~> N): (M ∙ G)#l ~> (N ∙ G)#l = f.asInstanceOf[(M ∙ G)#l ~> (N ∙ G)#l] // implemented with a cast to avoid extra object+method call. castless version: @@ -26,7 +28,6 @@ trait TypeFunctions implicit def toFn1[A,B](f: A => B): Fn1[A,B] = new Fn1[A,B] { def ∙[C](g: C => A) = f compose g } - def idK[M[_]]: M ~> M = new (M ~> M) { def apply[T](m: M[T]): M[T] = m } type Endo[T] = T=>T type ~>|[A[_],B[_]] = A ~> Compose[Option, B]#Apply diff --git a/util/collection/Types.scala b/util/collection/Types.scala index 42b81f990..d3a3420b0 100644 --- a/util/collection/Types.scala +++ b/util/collection/Types.scala @@ -4,15 +4,10 @@ package sbt object Types extends Types -{ - implicit def hconsToK[M[_], H, T <: HList](h: M[H] :+: T)(implicit mt: T => KList[M, T]): KList[M, H :+: T] = - KCons[H, T, M](h.head, mt(h.tail) ) - implicit def hnilToK(hnil: HNil): KNil = KNil -} trait Types extends TypeFunctions { val :^: = KCons - val :+: = HCons type :+:[H, T <: HList] = HCons[H,T] + val :+: = HCons } diff --git a/util/collection/src/test/scala/KListTest.scala b/util/collection/src/test/scala/KListTest.scala deleted file mode 100644 index 2ca25a31a..000000000 --- a/util/collection/src/test/scala/KListTest.scala +++ /dev/null @@ -1,19 +0,0 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah - */ -package sbt - -import Types._ - -object KTest { - val f = new (Option ~> List) { def apply[T](o: Option[T]): List[T] = o.toList } - - val x = Some(3) :^: Some("asdf") :^: KNil - val y = x transform f - val m1a = y match { case List(3) :^: List("asdf") :^: KNil => println("true") } - val m1b = (List(3) :^: KNil) match { case yy :^: KNil => println("true") } - - val head = new (List ~> Id) { def apply[T](xs: List[T]): T = xs.head } - val z = y down head - val m2 = z match { case 3 :+: "asdf" :+: HNil => println("true") } -} diff --git a/util/collection/src/test/scala/PMapTest.scala b/util/collection/src/test/scala/PMapTest.scala index bac4b7364..7970e175e 100644 --- a/util/collection/src/test/scala/PMapTest.scala +++ b/util/collection/src/test/scala/PMapTest.scala @@ -13,6 +13,7 @@ object PMapTest mp(Some(3)) = 9 val x = Some(3) :^: Some("asdf") :^: KNil val y = x.transform[Id](mp) - val z = y.down - z match { case 9 :+: "a" :+: HNil => println("true") } + assert(y.head == 9) + assert(y.tail.head == "a") + assert(y.tail.tail == KNil) } \ No newline at end of file diff --git a/util/collection/src/test/scala/SettingsExample.scala b/util/collection/src/test/scala/SettingsExample.scala index 558de7f4a..637f0ad51 100644 --- a/util/collection/src/test/scala/SettingsExample.scala +++ b/util/collection/src/test/scala/SettingsExample.scala @@ -49,7 +49,7 @@ object SettingsUsage // Define some settings val mySettings: Seq[Setting[_]] = Seq( setting( a3, value( 3 ) ), - setting( b4, app(a4 :^: KNil) { case av :+: HNil => av * 3 } ), + setting( b4, map(a4)(_ * 3)), update(a5)(_ + 1) )