From a15fb91c5c77be12d73c7f9b781c975c08daaa52 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 13 Dec 2023 14:01:57 +0100 Subject: [PATCH] Remove AList --- .../sbt/internal/util/appmacro/Cont.scala | 12 +- .../src/main/scala/sbt/Structure.scala | 109 +++++---- .../src/main/scala/sbt/std/Instances.scala | 35 +-- .../src/main/scala/sbt/std/TaskMacro.scala | 4 +- .../src/test/scala/sbt/TupleSyntaxTest.scala | 1 - sbt-app/src/main/scala/sbt/Import.scala | 2 - tasks-standard/src/main/scala/sbt/Task.scala | 6 +- .../src/main/scala/sbt/internal/Action.scala | 18 +- .../src/main/scala/sbt/std/TaskExtra.scala | 94 ++++---- .../src/main/scala/sbt/std/Transform.scala | 35 +-- tasks-standard/src/test/scala/Test.scala | 8 +- tasks/src/main/scala/sbt/Execute.scala | 10 +- tasks/src/main/scala/sbt/Node.scala | 13 +- .../main/scala/sbt/internal/util/AList.scala | 220 ------------------ .../main/scala/sbt/internal/util/INode.scala | 47 ++-- .../scala/sbt/internal/util/Settings.scala | 100 ++++---- .../sbt/internal/util/TupleMapExtension.scala | 32 +++ .../sbt/internal/util/TypeFunctions.scala | 5 - .../src/test/scala/AListTest.scala | 22 -- .../test/scala/TupleMapExtensionTest.scala | 13 ++ 20 files changed, 273 insertions(+), 513 deletions(-) delete mode 100644 util-collection/src/main/scala/sbt/internal/util/AList.scala create mode 100644 util-collection/src/main/scala/sbt/internal/util/TupleMapExtension.scala delete mode 100644 util-collection/src/test/scala/AListTest.scala create mode 100644 util-collection/src/test/scala/TupleMapExtensionTest.scala diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala index db4ad067ec8..b8afeff4f03 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala @@ -4,11 +4,9 @@ package util package appmacro import scala.collection.mutable.ListBuffer -import scala.reflect.TypeTest import scala.quoted.* import sbt.util.Applicative import sbt.util.Monad -import Types.Id /** * Implementation of a macro that provides a direct syntax for applicative functors and monads. It @@ -237,13 +235,9 @@ trait Cont: case '[inputTypeTpe] => '{ given Applicative[F] = $instanceExpr - AList - .tuple[inputTypeTpe & Tuple] - .mapN[F, A1](${ - br.tupleExpr.asInstanceOf[Expr[Tuple.Map[inputTypeTpe & Tuple, F]]] - })( - ${ lambda.asExprOf[Tuple.Map[inputTypeTpe & Tuple, Id] => A1] } - ) + import TupleMapExtension.* + ${ br.tupleExpr.asInstanceOf[Expr[Tuple.Map[inputTypeTpe & Tuple, F]]] } + .mapN(${ lambda.asExprOf[inputTypeTpe & Tuple => A1] }) } eitherTree match diff --git a/main-settings/src/main/scala/sbt/Structure.scala b/main-settings/src/main/scala/sbt/Structure.scala index ded747f2550..69304e9ba64 100644 --- a/main-settings/src/main/scala/sbt/Structure.scala +++ b/main-settings/src/main/scala/sbt/Structure.scala @@ -9,8 +9,9 @@ package sbt import scala.annotation.targetName -import sbt.internal.util.Types._ -import sbt.internal.util.{ ~>, AList, AttributeKey, Settings, SourcePosition } +import sbt.internal.util.Types.* +import sbt.internal.util.{ ~>, AttributeKey, Settings, SourcePosition } +import sbt.internal.util.TupleMapExtension.* import sbt.util.OptJsonWriter import sbt.ConcurrentRestrictions.Tag import sbt.Def.{ Initialize, ScopedKey, Setting, setting } @@ -354,7 +355,7 @@ object Scoped: * one setting in order to define another setting. * @return currently bound value wrapped in `Initialize[Some[T]]`, or `Initialize[None]` if unbound. */ - final def ? : Initialize[Option[A1]] = Def.optional(scopedKey)(idFun) + final def ? : Initialize[Option[A1]] = Def.optional(scopedKey)(identity) /** * Creates an [[Def.Initialize]] with value bound to this key, or returns `i` parameter if unbound. @@ -504,7 +505,7 @@ object Scoped: def ? : Initialize[Task[Option[A1]]] = Def.optional(scopedKey) { case None => mktask { None } - case Some(t) => t map some[A1] + case Some(t) => t.map(Some.apply) } def ??[T >: A1](or: => T): Initialize[Task[T]] = Def.optional(scopedKey)(_ getOrElse mktask(or)) @@ -534,9 +535,7 @@ object Scoped: .apply(deps => nop.dependsOn(deps: _*)) } - sealed abstract class RichTaskables[K[+L[x]]](final val keys: K[Taskable])(using - a: AList[K] - ): + sealed abstract class RichTaskables[Tup <: Tuple](final val keys: Tuple.Map[Tup, Taskable]): type App[T] = Initialize[Task[T]] @@ -544,90 +543,91 @@ object Scoped: type Fun[M[_], Ret] /** Convert the higher-kinded function to a Function1. For tuples that means call `.tupled`. */ - protected def convert[M[_], Ret](f: Fun[M, Ret]): K[M] => Ret + protected def convertK[M[_], Ret](f: Fun[M, Ret]): Tuple.Map[Tup, M] => Ret - private[this] val inputs: K[App] = a.transform(keys) { - [A] => (fa: Taskable[A]) => fa.toTask - } + private def convert[Ret](f: Fun[Id, Ret]): Tup => Ret = convertK(f).asInstanceOf + + private[this] val inputs: Tuple.Map[Tup, App] = + keys.transform { [A] => (fa: Taskable[A]) => fa.toTask } - private[this] def onTasks[A1](f: K[Task] => Task[A1]): App[A1] = - Def.app[SplitK[K, Task], Task[A1]](inputs)(f)(AList.asplit[K, Task](a)) + private[this] def onTasks[A1](f: Tuple.Map[Tup, Task] => Task[A1]): App[A1] = + Def.app[Tuple.Map[Tup, Task], Task[A1]](inputs.asInstanceOf)(f) def flatMapN[T](f: Fun[Id, Task[T]]): App[T] = onTasks(_.flatMapN(convert(f))) - def flatMapR[T](f: Fun[Result, Task[T]]): App[T] = onTasks(_.flatMapR(convert(f))) - def mapN[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) + def flatMapR[T](f: Fun[Result, Task[T]]): App[T] = onTasks(_.flatMapR(convertK(f))) + def mapN[T](f: Fun[Id, T]): App[T] = onTasks(_.mapR(convert(f).compose(allM))) + def mapR[T](f: Fun[Result, T]): App[T] = onTasks(_.mapR(convertK(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)) end RichTaskables // format: off type ST[X] = Taskable[X] - final class RichTaskable1[A1](t1: ST[A1]) extends RichTaskables[[F[_]] =>> F[A1]](t1)(using AList.single[A1]): + final class RichTaskable1[A1](t1: Tuple1[ST[A1]]) extends RichTaskables[Tuple1[A1]](t1): type Fun[M[_], Ret] = M[A1] => Ret def identityMap = mapN(identity) - protected def convert[M[_], R](f: M[A1] => R) = f + protected def convertK[M[_], R](f: M[A1] => R) = { case Tuple1(x) => f(x) } end RichTaskable1 - final class RichTaskable2[A, B](t2: (ST[A], ST[B])) extends RichTaskables[AList.Tuple2K[A, B]](t2)(using AList.tuple2[A, B]) { + final class RichTaskable2[A, B](t2: (ST[A], ST[B])) extends RichTaskables[(A, B)](t2) { type Fun[M[_], Ret] = (M[A], M[B]) => Ret def identityMap = mapN(mkTuple2) - protected def convert[M[_], R](f: (M[A], M[B]) => R) = f.tupled + protected def convertK[M[_], R](f: (M[A], M[B]) => R) = f.tupled } - final class RichTaskable3[A, B, C](t3: (ST[A], ST[B], ST[C])) extends RichTaskables[AList.Tuple3K[A, B, C]](t3)(using AList.tuple3[A, B, C]) { + final class RichTaskable3[A, B, C](t3: (ST[A], ST[B], ST[C])) extends RichTaskables[(A, B, C)](t3) { type Fun[M[_], Ret] = (M[A], M[B], M[C]) => Ret def identityMap = mapN(mkTuple3) - protected def convert[M[_], R](f: Fun[M, R]) = f.tupled + protected def convertK[M[_], R](f: Fun[M, R]) = f.tupled } - final class RichTaskable4[A, B, C, D](t4: (ST[A], ST[B], ST[C], ST[D])) extends RichTaskables[AList.Tuple4K[A, B, C, D]](t4)(using AList.tuple4[A, B, C, D]) { + final class RichTaskable4[A, B, C, D](t4: (ST[A], ST[B], ST[C], ST[D])) extends RichTaskables[(A, B, C, D)](t4) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D]) => Ret def identityMap = mapN(mkTuple4) - protected def convert[M[_], R](f: Fun[M, R]) = f.tupled + protected def convertK[M[_], R](f: Fun[M, R]) = f.tupled } - final class RichTaskable5[A, B, C, D, E](t5: (ST[A], ST[B], ST[C], ST[D], ST[E])) extends RichTaskables[AList.Tuple5K[A, B, C, D, E]](t5)(using AList.tuple5[A, B, C, D, E]) { + final class RichTaskable5[A, B, C, D, E](t5: (ST[A], ST[B], ST[C], ST[D], ST[E])) extends RichTaskables[(A, B, C, D, E)](t5) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E]) => Ret def identityMap = mapN(mkTuple5) - protected def convert[M[_], R](f: Fun[M, R]) = f.tupled + protected def convertK[M[_], R](f: Fun[M, R]) = f.tupled } - 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.Tuple6K[A, B, C, D, E, F]](t6)(using AList.tuple6[A, B, C, D, E, F]) { + final class RichTaskable6[A, B, C, D, E, F](t6: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F])) extends RichTaskables[(A, B, C, D, E, F)](t6) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F]) => Ret def identityMap = mapN(mkTuple6) - protected def convert[M[_], R](z: Fun[M, R]) = z.tupled + protected def convertK[M[_], R](z: Fun[M, R]) = z.tupled } - 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.Tuple7K[A, B, C, D, E, F, G]](t7)(using AList.tuple7[A, B, C, D, E, F, G]) { + 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[(A, B, C, D, E, F, G)](t7) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G]) => Ret def identityMap = mapN(mkTuple7) - protected def convert[M[_], R](z: Fun[M, R]) = z.tupled + protected def convertK[M[_], R](z: Fun[M, R]) = z.tupled } - 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.Tuple8K[A, B, C, D, E, F, G, H]](t8)(using AList.tuple8[A, B, C, D, E, F, G, H]) { + 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[(A, B, C, D, E, F, G, H)](t8) { type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H]) => Ret def identityMap = mapN(mkTuple8) - protected def convert[M[_], R](z: Fun[M, R]) = z.tupled + protected def convertK[M[_], R](z: Fun[M, R]) = z.tupled } - 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.Tuple9K[A, B, C, D, E, F, G, H, I]](t9)(using AList.tuple9[A, B, C, D, E, F, G, H, I]) { + 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[(A, B, C, D, E, F, G, H, I)](t9) { 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 = mapN(mkTuple9) - protected def convert[M[_], R](z: Fun[M, R]) = z.tupled + protected def convertK[M[_], R](z: Fun[M, R]) = z.tupled } - 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.Tuple10K[A, B, C, D, E, F, G, H, I, J]](t10)(using AList.tuple10[A, B, C, D, E, F, G, H, I, J]) { + 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[(A, B, C, D, E, F, G, H, I, J)](t10) { 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 = mapN(mkTuple10) - protected def convert[M[_], R](z: Fun[M, R]) = z.tupled + protected def convertK[M[_], R](z: Fun[M, R]) = z.tupled } - 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.Tuple11K[A, B, C, D, E, F, G, H, I, J, K]](t11)(using AList.tuple11[A, B, C, D, E, F, G, H, I, J, K]) { + 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[(A, B, C, D, E, F, G, H, I, J, K)](t11) { 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 = mapN(mkTuple11) - protected def convert[M[_], R](z: Fun[M, R]) = z.tupled + protected def convertK[M[_], R](z: Fun[M, R]) = z.tupled } def mkTuple2[A, B] = (a: A, b: B) => (a, b) @@ -646,52 +646,52 @@ 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[R](z: (A, B) => R) = Def.app[AList.Tuple2K[A, B], R](t2)(z.tupled)(AList.tuple2[A, B]) + def apply[R](z: (A, B) => R) = Def.app[(A, B), R](t2)(z.tupled) def identity = apply(mkTuple2) end Apply2 final class Apply3[A, B, C](t3: (Initialize[A], Initialize[B], Initialize[C])): - def apply[T](z: (A, B, C) => T) = Def.app[AList.Tuple3K[A, B, C], T](t3)(z.tupled)(AList.tuple3[A, B, C]) + def apply[T](z: (A, B, C) => T) = Def.app[(A, B, C), T](t3)(z.tupled) def identity = apply(mkTuple3) end Apply3 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[AList.Tuple4K[A, B, C, D], T](t4)(z.tupled)(AList.tuple4[A, B, C, D]) + def apply[T](z: (A, B, C, D) => T) = Def.app[(A, B, C, D), T](t4)(z.tupled) def identity = apply(mkTuple4) end Apply4 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[AList.Tuple5K[A, B, C, D, E], T](t5)(z.tupled)(AList.tuple5[A, B, C, D, E]) + def apply[T](z: (A, B, C, D, E) => T) = Def.app[(A, B, C, D, E), T](t5)(z.tupled) def identity = apply(mkTuple5) end Apply5 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[AList.Tuple6K[A, B, C, D, E, F], T](t6)(z.tupled)(AList.tuple6[A, B, C, D, E, F]) + def apply[T](z: (A, B, C, D, E, F) => T) = Def.app[(A, B, C, D, E, F), T](t6)(z.tupled) def identity = apply(mkTuple6) end Apply6 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[AList.Tuple7K[A, B, C, D, E, F, G], T](t7)(z.tupled)(AList.tuple7[A, B, C, D, E, F, G]) + def apply[T](z: (A, B, C, D, E, F, G) => T) = Def.app[(A, B, C, D, E, F, G), T](t7)(z.tupled) def identity = apply(mkTuple7) end Apply7 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[AList.Tuple8K[A, B, C, D, E, F, G, H], T](t8)(z.tupled)(AList.tuple8[A, B, C, D, E, F, G, H]) + def apply[T](z: (A, B, C, D, E, F, G, H) => T) = Def.app[(A, B, C, D, E, F, G, H), T](t8)(z.tupled) def identity = apply(mkTuple8) end Apply8 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[AList.Tuple9K[A, B, C, D, E, F, G, H, I], T](t9)(z.tupled)(AList.tuple9[A, B, C, D, E, F, G, H, I]) + def apply[T](z: (A, B, C, D, E, F, G, H, I) => T) = Def.app[(A, B, C, D, E, F, G, H, I), T](t9)(z.tupled) def identity = apply(mkTuple9) end Apply9 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[AList.Tuple10K[A, B, C, D, E, F, G, H, I, J], T](t10)(z.tupled)(AList.tuple10[A, B, C, D, E, F, G, H, I, J]) + def apply[T](z: (A, B, C, D, E, F, G, H, I, J) => T) = Def.app[(A, B, C, D, E, F, G, H, I, J), T](t10)(z.tupled) def identity = apply(mkTuple10) end Apply10 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[AList.Tuple11K[A, B, C, D, E, F, G, H, I, J, K], T](t11)(z.tupled)(AList.tuple11[A, B, C, D, E, F, G, H, I, J, K]) + def apply[T](z: (A, B, C, D, E, F, G, H, I, J, K) => T) = Def.app[(A, B, C, D, E, F, G, H, I, J, K), T](t11)(z.tupled) def identity = apply(mkTuple11) end Apply11 @@ -713,7 +713,7 @@ trait TupleSyntax: // this is the least painful arrangement I came up with type ST[T] = Taskable[T] - implicit def taskableToTable1[A1](t1: ST[A1]): RichTaskable1[A1] = new RichTaskable1(t1) + implicit def taskableToTable1[A1](t1: ST[A1]): RichTaskable1[A1] = new RichTaskable1(Tuple1(t1)) implicit def t2ToTable2[A, B](t2: (ST[A], ST[B])): RichTaskable2[A, B] = new RichTaskable2(t2) implicit def t3ToTable3[A, B, C](t3: (ST[A], ST[B], ST[C])): RichTaskable3[A, B, C] = new RichTaskable3(t3) implicit def t4ToTable4[A, B, C, D](t4: (ST[A], ST[B], ST[C], ST[D])): RichTaskable4[A, B, C, D] = new RichTaskable4(t4) @@ -898,9 +898,6 @@ end SettingKey class TupleWrap[Tup <: Tuple](value: Tuple.Map[Tup, Taskable]): type InitTask[A2] = Initialize[Task[A2]] - lazy val alist = AList.tuple[Tup] - lazy val initTasks = - alist.transform[Taskable, InitTask](value)([a] => (t: Taskable[a]) => t.toTask) + lazy val initTasks = value.transform[InitTask]([a] => (t: Taskable[a]) => t.toTask) def mapN[A1](f: Tup => A1): Def.Initialize[Task[A1]] = - import std.FullInstance.initializeTaskMonad - alist.mapN[InitTask, A1](initTasks)(f.asInstanceOf[Tuple.Map[Tup, Id] => A1]) + initTasks.mapN[A1](f)(using std.FullInstance.initializeTaskMonad) diff --git a/main-settings/src/main/scala/sbt/std/Instances.scala b/main-settings/src/main/scala/sbt/std/Instances.scala index 5b4a4ef407e..3ea614a4fe5 100644 --- a/main-settings/src/main/scala/sbt/std/Instances.scala +++ b/main-settings/src/main/scala/sbt/std/Instances.scala @@ -10,8 +10,7 @@ package std import Def.Initialize import sbt.util.{ Applicative, Monad } -import sbt.internal.util.AList -import sbt.internal.util.Types.{ const, Id, Compose, idFun } +import sbt.internal.util.Types.{ const, Compose } import sbt.internal.util.complete.{ DefaultParsers, Parser } object InitializeInstance: @@ -80,33 +79,19 @@ object FullInstance: FullInstance.flatten[A1](in) def flatten[A1](in: Initialize[Task[Initialize[Task[A1]]]]): Initialize[Task[A1]] = - type K[L[x]] = - AList.Tuple3K[Task[Initialize[Task[A1]]], Task[SS], [a] => Initialize[a] => Initialize[a]][ - L - ] - Def.app[K, Task[A1]]((in, settingsData, Def.capturedTransformations)) { + type Tup = (Task[Initialize[Task[A1]]], Task[SS], [a] => Initialize[a] => Initialize[a]) + Def.app[Tup, Task[A1]]((in, settingsData, Def.capturedTransformations)) { case (a: Task[Initialize[Task[A1]]], data: Task[SS], f) => - import TaskExtra.multT2Task - (a, data).flatMapN { case (a, d) => f(a) evaluate d } - }(AList.tuple3[Task[Initialize[Task[A1]]], Task[SS], [a] => Initialize[a] => Initialize[a]]) + TaskExtra.multT2Task((a, data)).flatMapN { case (a, d) => f(a) evaluate d } + } def flattenFun[A1, A2]( in: Initialize[Task[A1 => Initialize[Task[A2]]]] ): Initialize[A1 => Task[A2]] = - type K[L[x]] = - AList.Tuple3K[Task[A1 => Initialize[Task[A2]]], Task[SS], [a] => Initialize[a] => Initialize[ - a - ]][L] - Def.app[K, A1 => Task[A2]]((in, settingsData, Def.capturedTransformations)) { - case (a: Task[A1 => Initialize[Task[A2]]] @unchecked, data: Task[SS] @unchecked, f) => { - (s: A1) => - import TaskExtra.multT2Task - (a, data) flatMapN { case (af, d) => f(af(s)) evaluate d } - } - }( - AList.tuple3[Task[A1 => Initialize[Task[A2]]], Task[SS], [a] => Initialize[a] => Initialize[ - a - ]] - ) + type Tup = (Task[A1 => Initialize[Task[A2]]], Task[SS], [a] => Initialize[a] => Initialize[a]) + Def.app[Tup, A1 => Task[A2]]((in, settingsData, Def.capturedTransformations)) { + case (a: Task[A1 => Initialize[Task[A2]]] @unchecked, data: Task[SS] @unchecked, f) => + (s: A1) => TaskExtra.multT2Task((a, data)).flatMapN { case (af, d) => f(af(s)) evaluate d } + } end FullInstance diff --git a/main-settings/src/main/scala/sbt/std/TaskMacro.scala b/main-settings/src/main/scala/sbt/std/TaskMacro.scala index 03314a1cb4e..29677d2e17f 100644 --- a/main-settings/src/main/scala/sbt/std/TaskMacro.scala +++ b/main-settings/src/main/scala/sbt/std/TaskMacro.scala @@ -10,7 +10,7 @@ package std import Def.{ Initialize, Setting } import sbt.util.{ Applicative, Monad } -import sbt.internal.util.Types.{ Id, Compose, const, idFun } +import sbt.internal.util.Types.Id import sbt.internal.util.appmacro.{ Cont, ContextUtil, @@ -21,7 +21,7 @@ import sbt.internal.util.appmacro.{ // MonadInstance } // import Instance.Transform -import sbt.internal.util.{ AList, LinePosition, NoPosition, SourcePosition, ~> } +import sbt.internal.util.{ LinePosition, NoPosition, SourcePosition, ~> } import language.experimental.macros import scala.annotation.tailrec diff --git a/main-settings/src/test/scala/sbt/TupleSyntaxTest.scala b/main-settings/src/test/scala/sbt/TupleSyntaxTest.scala index bbb1899e2bd..e2c59d8065b 100644 --- a/main-settings/src/test/scala/sbt/TupleSyntaxTest.scala +++ b/main-settings/src/test/scala/sbt/TupleSyntaxTest.scala @@ -9,7 +9,6 @@ package sbt.test import sbt._ import sbt.Def.Initialize -import sbt.internal.util.AList import sbt.internal.util.Types.Id object TupleSyntaxTest: diff --git a/sbt-app/src/main/scala/sbt/Import.scala b/sbt-app/src/main/scala/sbt/Import.scala index 200c5c4fb2e..41eb0ba86fd 100644 --- a/sbt-app/src/main/scala/sbt/Import.scala +++ b/sbt-app/src/main/scala/sbt/Import.scala @@ -121,8 +121,6 @@ trait Import { val Tracked = sbt.util.Tracked // sbt.internal.util - val AList = sbt.internal.util.AList - type AList[K[L[x]]] = sbt.internal.util.AList[K] type AbstractRMap[K[_], V[_]] = sbt.internal.util.AbstractRMap[K, V] type AlreadyHandledException = sbt.internal.util.AlreadyHandledException val AttributeEntry = sbt.internal.util.AttributeEntry diff --git a/tasks-standard/src/main/scala/sbt/Task.scala b/tasks-standard/src/main/scala/sbt/Task.scala index f56c6965e33..5a79c5bd6f5 100644 --- a/tasks-standard/src/main/scala/sbt/Task.scala +++ b/tasks-standard/src/main/scala/sbt/Task.scala @@ -8,8 +8,8 @@ package sbt import sbt.internal.Action -import sbt.internal.util.Types._ -import sbt.internal.util.{ ~>, AList, AttributeKey, AttributeMap } +import sbt.internal.util.Types.const +import sbt.internal.util.{ ~>, AttributeKey, AttributeMap } import ConcurrentRestrictions.{ Tag, TagMap, tagsKey } import sbt.util.Monad @@ -51,7 +51,7 @@ object Task: override def map[A1, A2](in: Task[A1])(f: A1 => A2): Task[A2] = in.map(f) override def flatMap[A1, A2](in: F[A1])(f: A1 => F[A2]): F[A2] = in.flatMap(f) - override def flatten[A1](in: Task[Task[A1]]): Task[A1] = in.flatMap(idFun[Task[A1]]) + override def flatten[A1](in: Task[Task[A1]]): Task[A1] = in.flatMap(identity) end Task /** diff --git a/tasks-standard/src/main/scala/sbt/internal/Action.scala b/tasks-standard/src/main/scala/sbt/internal/Action.scala index bd041aa38e1..77baca4bb73 100644 --- a/tasks-standard/src/main/scala/sbt/internal/Action.scala +++ b/tasks-standard/src/main/scala/sbt/internal/Action.scala @@ -8,8 +8,6 @@ package sbt package internal -import sbt.internal.util.AList - // Action, Task, and Info are intentionally invariant in their type parameter. // Various natural transformations used, such as PMap, require invariant type constructors for correctness @@ -27,14 +25,14 @@ enum Action[A]: // private[sbt] def mapTask(f: [A1] => Task[A1] => Task[A1]) = this /** Applies a function to the result of evaluating a heterogeneous list of other tasks. */ - case Mapped[A, K[+F[_]]](in: K[Task], f: K[Result] => A, alist: AList[K]) extends Action[A] + case Mapped[A, Tup <: Tuple](in: Tuple.Map[Tup, Task], f: Tuple.Map[Tup, Result] => A) + extends Action[A] // private[sbt] def mapTask(g: Task ~> Task) = Mapped[A, K](alist.transform(in, g), f, alist) /** Computes another task to evaluate based on results from evaluating other tasks. */ - case FlatMapped[A, K[+F[_]]]( - in: K[Task], - f: K[Result] => Task[A], - alist: AList[K], + case FlatMapped[A, Tup <: Tuple]( + in: Tuple.Map[Tup, Task], + f: Tuple.Map[Tup, Result] => Task[A] ) extends Action[A] // private[sbt] def mapTask(g: Task ~> Task) = // FlatMapped[A, K](alist.transform(in, g), g.fn[A] compose f, alist) @@ -70,15 +68,13 @@ object Action: */ private[sbt] def asFlatMapped[A1, A2]( s: Action.Selected[A1, A2] - ): Action.FlatMapped[A2, [F[_]] =>> Tuple1[F[Either[A1, A2]]]] = - val alist = AList.tuple[Tuple1[Either[A1, A2]]] + ): Action.FlatMapped[A2, Tuple1[Either[A1, A2]]] = val f: Either[A1, A2] => Task[A2] = { case Right(b) => task(b) case Left(a) => singleInputTask(s.fin).map(_(a)) } - Action.FlatMapped[A2, [F[_]] =>> Tuple1[F[Either[A1, A2]]]]( + Action.FlatMapped[A2, Tuple1[Either[A1, A2]]]( Tuple1(s.fab), { case Tuple1(r) => f.compose(successM)(r) }, - alist, ) end Action diff --git a/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala b/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala index b42da208b6c..d04d08a3c6a 100644 --- a/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala +++ b/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala @@ -10,17 +10,17 @@ package std import scala.sys.process.{ BasicIO, ProcessIO, ProcessBuilder } -import sbt.internal.util.{ AList, AttributeMap } -import sbt.internal.util.Types._ +import sbt.internal.util.AttributeMap +import sbt.internal.util.TupleMapExtension.* import java.io.{ BufferedInputStream, BufferedReader, File, InputStream } import sbt.io.IO import sbt.internal.Action -sealed trait MultiInTask[K[F[_]]] { - def flatMapN[A](f: K[Id] => Task[A]): Task[A] - def flatMapR[A](f: K[Result] => Task[A]): Task[A] - def mapN[A](f: K[Id] => A): Task[A] - def mapR[A](f: K[Result] => A): Task[A] +sealed trait MultiInTask[Tup <: Tuple] { + def flatMapN[A](f: Tup => Task[A]): Task[A] + def flatMapR[A](f: Tuple.Map[Tup, Result] => Task[A]): Task[A] + def mapN[A](f: Tup => A): Task[A] + def mapR[A](f: Tuple.Map[Tup, Result] => A): Task[A] def flatFailure[A](f: Seq[Incomplete] => Task[A]): Task[A] def mapFailure[A](f: Seq[Incomplete] => A): Task[A] } @@ -123,7 +123,7 @@ trait TaskExtra extends TaskExtra0 { 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) + def tasks: Seq[Task[S]] = fork(identity) } import TaskExtra.{ allM, anyFailM, failM, successM } @@ -134,75 +134,62 @@ trait TaskExtra extends TaskExtra0 { def reduced(f: (S, S) => S): Task[S] = TaskExtra.reduced(in.toIndexedSeq, f) } - final implicit def multT2Task[A1, A2]( - in: (Task[A1], Task[A2]) - ): MultiInTask[[F[_]] =>> Tuple.Map[(A1, A2), F]] = - given AList[[F[_]] =>> Tuple.Map[(A1, A2), F]] = AList.tuple[(A1, A2)] - multInputTask[[F[_]] =>> Tuple.Map[(A1, A2), F]](in) + final implicit def multT2Task[A1, A2](in: (Task[A1], Task[A2])): MultiInTask[(A1, A2)] = + multInputTask[(A1, A2)](in) - given multT2TaskConv[A1, A2] - : Conversion[(Task[A1], Task[A2]), MultiInTask[[F[_]] =>> Tuple.Map[(A1, A2), F]]] = + given multT2TaskConv[A1, A2]: Conversion[(Task[A1], Task[A2]), MultiInTask[(A1, A2)]] = multT2Task(_) - final implicit def multInputTask[K[+F[_]]: AList](tasks: K[Task]): MultiInTask[K] = - new MultiInTask[K]: - override def flatMapN[A](f: K[Id] => Task[A]): Task[A] = - Task(Info(), Action.FlatMapped[A, K](tasks, f compose allM, AList[K])) - override def flatMapR[A](f: K[Result] => Task[A]): Task[A] = - Task(Info(), Action.FlatMapped[A, K](tasks, f, AList[K])) - - override def mapN[A](f: K[Id] => A): Task[A] = - Task(Info(), Action.Mapped[A, K](tasks, f compose allM, AList[K])) - override def mapR[A](f: K[Result] => A): Task[A] = - Task(Info(), Action.Mapped[A, K](tasks, f, AList[K])) + final implicit def multInputTask[Tup <: Tuple](tasks: Tuple.Map[Tup, Task]): MultiInTask[Tup] = + new MultiInTask[Tup]: + override def flatMapN[A](f: Tup => Task[A]): Task[A] = + Task(Info(), Action.FlatMapped(tasks, f.compose(allM))) + override def flatMapR[A](f: Tuple.Map[Tup, Result] => Task[A]): Task[A] = + Task(Info(), Action.FlatMapped(tasks, f)) + + override def mapN[A](f: Tup => A): Task[A] = + Task(Info(), Action.Mapped(tasks, f.compose(allM))) + override def mapR[A](f: Tuple.Map[Tup, Result] => A): Task[A] = + Task(Info(), Action.Mapped(tasks, f)) override def flatFailure[A](f: Seq[Incomplete] => Task[A]): Task[A] = - Task(Info(), Action.FlatMapped[A, K](tasks, f compose anyFailM, AList[K])) + Task(Info(), Action.FlatMapped(tasks, f.compose(anyFailM))) override def mapFailure[A](f: Seq[Incomplete] => A): Task[A] = - Task(Info(), Action.Mapped[A, K](tasks, f compose anyFailM, AList[K])) + Task(Info(), Action.Mapped(tasks, f.compose(anyFailM))) final implicit def singleInputTask[S](in: Task[S]): SingleInTask[S] = new SingleInTask[S]: // type K[L[x]] = L[S] - given alist: AList[[F[_]] =>> Tuple.Map[Tuple1[S], F]] = AList.tuple[Tuple1[S]] - def failure: Task[Incomplete] = mapFailure(idFun) - def result: Task[Result[S]] = mapR(idFun) + def failure: Task[Incomplete] = mapFailure(identity) + def result: Task[Result[S]] = mapR(identity) private def newInfo[A]: Info[A] = TaskExtra.newInfo(in.info) override def flatMapR[A](f: Result[S] => Task[A]): Task[A] = Task( newInfo, - Action.FlatMapped[A, [F[_]] =>> Tuple.Map[Tuple1[S], F]]( - AList.toTuple(in), - AList.fromTuple(f), - alist, - ) + Action.FlatMapped[A, Tuple1[S]](Tuple1(in), { case Tuple1(a) => f(a) }) ) override def mapR[A](f: Result[S] => A): Task[A] = Task( newInfo, - Action.Mapped[A, [F[_]] =>> Tuple.Map[Tuple1[S], F]]( - AList.toTuple(in), - AList.fromTuple(f), - alist, - ) + Action.Mapped[A, Tuple1[S]](Tuple1(in), { case Tuple1(a) => f(a) }) ) override def dependsOn(tasks: Task[_]*): Task[S] = Task(newInfo, Action.DependsOn(in, tasks)) - override def flatMapN[T](f: S => Task[T]): Task[T] = flatMapR(f compose successM) + override def flatMapN[T](f: S => Task[T]): Task[T] = flatMapR(f.compose(successM)) override inline def flatMap[T](f: S => Task[T]): Task[T] = flatMapN[T](f) - override def flatFailure[T](f: Incomplete => Task[T]): Task[T] = flatMapR(f compose failM) + override def flatFailure[T](f: Incomplete => Task[T]): Task[T] = flatMapR(f.compose(failM)) - override def mapN[T](f: S => T): Task[T] = mapR(f compose successM) + override def mapN[T](f: S => T): Task[T] = mapR(f.compose(successM)) override inline def map[T](f: S => T): Task[T] = mapN(f) - override def mapFailure[T](f: Incomplete => T): Task[T] = mapR(f compose failM) + override def mapFailure[T](f: Incomplete => T): Task[T] = mapR(f.compose(failM)) def andFinally(fin: => Unit): Task[S] = mapR(x => Result.tryValue[S]({ fin; x })) def doFinally(t: Task[Unit]): Task[S] = @@ -300,11 +287,10 @@ object TaskExtra extends TaskExtra { } def reducePair[A1](a: Task[A1], b: Task[A1], f: (A1, A1) => A1): Task[A1] = - given AList[[F[_]] =>> Tuple.Map[(A1, A1), F]] = AList.tuple[(A1, A1)] - multInputTask[[F[_]] =>> Tuple.Map[(A1, A1), F]]((a, b)) mapN f.tupled + multInputTask[(A1, A1)]((a, b)).mapN(f.tupled) - def anyFailM[K[F[_]]: AList]: K[Result] => Seq[Incomplete] = in => { - val incs = failuresM[K](AList[K])(in) + def anyFailM[Tup <: Tuple]: Tuple.Map[Tup, Result] => Seq[Incomplete] = in => { + val incs = failuresM[Tup](in) if incs.isEmpty then expectedFailure else incs } @@ -321,13 +307,13 @@ object TaskExtra extends TaskExtra { case Result.Value(a) => a } - def allM[K[F[_]]: AList]: K[Result] => K[Id] = in => { - val incs = failuresM[K](AList[K])(in) - if incs.isEmpty then AList[K].transform[Result, Id](in)(Result.tryValue) // .asInstanceOf + def allM[Tup <: Tuple]: Tuple.Map[Tup, Result] => Tup = in => { + val incs = failuresM[Tup](in) + if incs.isEmpty then in.unmap(Result.tryValue) else throw incompleteDeps(incs) } - def failuresM[K[F[_]]: AList]: K[Result] => Seq[Incomplete] = x => - failures[Any](AList[K].toList(x)) + def failuresM[Tup <: Tuple]: Tuple.Map[Tup, Result] => Seq[Incomplete] = x => + failures(x.iterator.toList) def all[D](in: Seq[Result[D]]): Seq[D] = { val incs = failures(in) diff --git a/tasks-standard/src/main/scala/sbt/std/Transform.scala b/tasks-standard/src/main/scala/sbt/std/Transform.scala index 238613e570b..b21bb26f091 100644 --- a/tasks-standard/src/main/scala/sbt/std/Transform.scala +++ b/tasks-standard/src/main/scala/sbt/std/Transform.scala @@ -9,8 +9,8 @@ package sbt package std import sbt.internal.Action -import sbt.internal.util.Types._ -import sbt.internal.util.{ ~>, AList, DelegatingPMap, RMap } +import sbt.internal.util.{ ~>, DelegatingPMap, RMap } +import sbt.internal.util.TupleMapExtension.* import TaskExtra.{ all, existToAny } import sbt.internal.util.Types.* @@ -49,15 +49,12 @@ object Transform: new NodeView: import Action.* def apply[T](t: TaskId[T]): Node[T] = pre(t).work match - case Pure(eval, _) => uniform(Nil)(_ => Right(eval())) - case m: Mapped[a, k] => toNode[a, k](m.in)(right[a] compose m.f)(m.alist) - case m: FlatMapped[a, k] => - toNode[a, k](m.in)(left[Task[a]] compose m.f)(m.alist) // (m.alist) + case Pure(eval, _) => uniform(Nil)(_ => Right(eval())) + case m: Mapped[a, t] => toNode(m.in)(right[a].compose(m.f)) + case m: FlatMapped[a, t] => toNode(m.in)(left[Task[a]].compose(m.f)) case s: Selected[a1, a2] => val m = Action.asFlatMapped[a1, a2](s) - toNode[a2, [F[_]] =>> Tuple1[F[Either[a1, a2]]]](m.in)(left[Task[a2]] compose m.f)( - m.alist - ) + toNode(m.in)(left[Task[a2]].compose(m.f)) case DependsOn(in, deps) => uniform(existToAny(deps))(const(Left(in)) compose all) case Join(in, f) => uniform(in)(f) @@ -68,15 +65,19 @@ object Transform: def uniform[A1, D](tasks: Seq[Task[D]])( f: Seq[Result[D]] => Either[Task[A1], A1] ): Node[A1] = - toNode[A1, [F[_]] =>> List[F[D]]](tasks.toList)(f)(AList.list[D]) + new Node[A1]: + type Inputs = Seq[Result[D]] + def dependencies: List[TaskId[D]] = tasks.toList + def computeInputs(f: [a] => (x: TaskId[a]) => Result[a]): Inputs = tasks.map(f[D]) + def work(inputs: Inputs) = f(inputs) - def toNode[A1, K1[F[_]]: AList]( - inputs: K1[TaskId] - )(f: K1[Result] => Either[Task[A1], A1]): Node[A1] = + def toNode[A1, Tup <: Tuple]( + deps: Tuple.Map[Tup, TaskId] + )(f: Tuple.Map[Tup, Result] => Either[Task[A1], A1]): Node[A1] = new Node[A1]: - type K[F[_]] = K1[F] - val in = inputs - lazy val alist: AList[K] = AList[K] - def work(results: K[Result]) = f(results) + type Inputs = Tuple.Map[Tup, Result] + def dependencies: List[TaskId[?]] = deps.iterator.toList + def computeInputs(f: [a] => TaskId[a] => Result[a]) = deps.transform(f) + def work(inputs: Inputs) = f(inputs) end Transform diff --git a/tasks-standard/src/test/scala/Test.scala b/tasks-standard/src/test/scala/Test.scala index 11dc6f62c1c..34447cebd4d 100644 --- a/tasks-standard/src/test/scala/Test.scala +++ b/tasks-standard/src/test/scala/Test.scala @@ -7,15 +7,11 @@ package sbt -import sbt.internal.util.AList - object Test extends std.TaskExtra: def t2[A1, A2](a1: Task[A1], a2: Task[A2]) = - given AList[[F[_]] =>> Tuple.Map[(A1, A2), F]] = AList.tuple[(A1, A2)] - multInputTask[[F[_]] =>> Tuple.Map[(A1, A2), F]]((a1, a2)) + multInputTask[(A1, A2)]((a1, a2)) def t3[A1, A2, A3](a1: Task[A1], a2: Task[A2], a3: Task[A3]) = - given AList[[F[_]] =>> Tuple.Map[(A1, A2, A3), F]] = AList.tuple[(A1, A2, A3)] - multInputTask[[F[_]] =>> Tuple.Map[(A1, A2, A3), F]]((a1, a2, a3)) + multInputTask[(A1, A2, A3)]((a1, a2, a3)) val a = task(3) val b = task[Boolean](sys.error("test")) diff --git a/tasks/src/main/scala/sbt/Execute.scala b/tasks/src/main/scala/sbt/Execute.scala index 4c9a39c1409..963819f050b 100644 --- a/tasks/src/main/scala/sbt/Execute.scala +++ b/tasks/src/main/scala/sbt/Execute.scala @@ -11,14 +11,13 @@ import java.util.concurrent.ExecutionException import sbt.internal.util.ErrorHandling.wideConvert import sbt.internal.util.{ DelegatingPMap, IDSet, PMap, RMap, ~> } -import sbt.internal.util.Types.* +import sbt.internal.util.Types.const import sbt.internal.util.Util.nilSeq import scala.annotation.tailrec import scala.collection.mutable import scala.jdk.CollectionConverters.* import mutable.Map -import sbt.internal.util.AList private[sbt] object Execute { def taskMap[A]: Map[TaskId[?], A] = (new java.util.IdentityHashMap[TaskId[?], A]).asScala @@ -28,7 +27,7 @@ private[sbt] object Execute { private[sbt] def completed(p: => Unit): Completed = new Completed { def process(): Unit = p } - def noTriggers[TaskId[_]] = new Triggers(Map.empty, Map.empty, idFun) + def noTriggers[TaskId[_]] = new Triggers(Map.empty, Map.empty, identity) def config(checkCycles: Boolean, overwriteNode: Incomplete => Boolean = const(false)): Config = new Config(checkCycles, overwriteNode) @@ -280,8 +279,7 @@ private[sbt] final class Execute( /** Send the work for this node to the provided Strategy. */ def submit(node: TaskId[?])(using strategy: CompletionService): Unit = { val v = viewCache(node) - val rs = v.alist.transform(v.in)(getResult) - // v.alist.transform(v.in)(getResult) + val rs = v.computeInputs(getResult) strategy.submit(node, () => work(node, v.work(rs))) } @@ -325,7 +323,7 @@ private[sbt] final class Execute( def dependencies(node: TaskId[?]): Iterable[TaskId[?]] = dependencies(viewCache(node)) def dependencies(v: Node[?]): Iterable[TaskId[?]] = - v.alist.toList(v.in).filter(dep => view.inline1(dep).isEmpty) + v.dependencies.filter(dep => view.inline1(dep).isEmpty) def runBefore(node: TaskId[?]): Seq[TaskId[?]] = triggers.runBefore.getOrElse(node, nilSeq) def triggeredBy(node: TaskId[?]): Seq[TaskId[?]] = triggers.injectFor.getOrElse(node, nilSeq) diff --git a/tasks/src/main/scala/sbt/Node.scala b/tasks/src/main/scala/sbt/Node.scala index eb211dba7cf..c58a96fe170 100644 --- a/tasks/src/main/scala/sbt/Node.scala +++ b/tasks/src/main/scala/sbt/Node.scala @@ -7,21 +7,16 @@ package sbt -import sbt.internal.util.AList - /** * Represents a task node in a format understood by the task evaluation engine Execute. - * - * @tparam Effect - * the task type constructor * @tparam A * the type computed by this node */ private[sbt] trait Node[A]: - type K[L[x]] - def in: K[TaskId] - def alist: AList[K] + type Inputs + def dependencies: List[TaskId[?]] + def computeInputs(f: [a] => TaskId[a] => Result[a]): Inputs /** Computes the result of this task given the results from the inputs. */ - def work(inputs: K[Result]): Either[TaskId[A], A] + def work(inputs: Inputs): Either[TaskId[A], A] end Node diff --git a/util-collection/src/main/scala/sbt/internal/util/AList.scala b/util-collection/src/main/scala/sbt/internal/util/AList.scala deleted file mode 100644 index 28f3ff33088..00000000000 --- a/util-collection/src/main/scala/sbt/internal/util/AList.scala +++ /dev/null @@ -1,220 +0,0 @@ -/* - * sbt - * Copyright 2011 - 2018, Lightbend, Inc. - * Copyright 2008 - 2010, Mark Harrah - * Licensed under Apache License 2.0 (see LICENSE) - */ - -package sbt.internal -package util - -import sbt.util.Applicative -import Types._ - -/** - * Arity-generic List. An abstraction over structured Tuple/List type constructor `X1[f[a]]`. - */ -trait AList[K[F[_]]]: - import AList.idPoly - - def transform[F1[_], F2[_]](value: K[F1])( - f: [a] => F1[a] => F2[a] - ): K[F2] - - def traverse[F1[_], F2[_]: Applicative](value: K[F1])( - f: [a] => F1[a] => F2[a] - ): F2[K[Id]] - - def mapN[F1[_]: Applicative, A1](value: K[F1])(f: K[Id] => A1): F1[A1] = - summon[Applicative[F1]].map(traverse[F1, F1](value)(idPoly[F1]))(f) - - def traverseX[F1[_], F2[_]: Applicative, P[_]](value: K[F1])( - f: [a] => F1[a] => F2[P[a]] - ): F2[K[P]] - - def foldr[F1[_], A1](value: K[F1], init: A1)( - f: [a] => (F1[a], A1) => A1 - ): A1 - - def toList[F1[_]](value: K[F1]): List[F1[Any]] = - val f = [a] => (p1: F1[a], p2: List[F1[Any]]) => p1.asInstanceOf[F1[Any]] :: p2 - foldr[F1, List[F1[Any]]](value, Nil)(f) -end AList - -object AList: - inline def apply[K[F[_]]: AList]: AList[K] = summon[AList[K]] - - type Tail[X <: Tuple] <: Tuple = X match - case _ *: xs => xs - - def idPoly[F1[_]] = [a] => (p: F1[a]) => p - - def nil[Tup <: Tuple] = EmptyTuple.asInstanceOf[Tup] - - inline def toTuple[A](a: A): Tuple1[A] = Tuple1(a) - - inline def fromTuple[A1, A2](f: A1 => A2): Tuple1[A1] => A2 = { case Tuple1(a) => f(a) } - - // givens for tuple map - given [Tup <: Tuple]: AList[[F[_]] =>> Tuple.Map[Tup, F]] = tuple[Tup] - - type Empty = AList[[F[_]] =>> Unit] - - lazy val empty: Empty = new Empty: - override def transform[F1[_], F2[_]](value: Unit)(f: [x] => F1[x] => F2[x]): Unit = () - override def traverse[F1[_], F2[_]: Applicative](value: Unit)( - f: [a] => F1[a] => F2[a] - ): F2[Unit] = summon[Applicative[F2]].pure(() => ()) - override def traverseX[F1[_], F2[_]: Applicative, P[_]](value: Unit)( - f: [a] => F1[a] => F2[P[a]] - ): F2[Unit] = summon[Applicative[F2]].pure(() => ()) - override def foldr[F1[_], A2](value: Unit, init: A2)( - f: [a] => (F1[a], A2) => A2 - ): A2 = init - - type Single[A1] = AList[[F[_]] =>> F[A1]] - - def single[A1]: Single[A1] = new Single[A1]: - override def transform[F1[_], F2[_]](value: F1[A1])(f: [x] => F1[x] => F2[x]): F2[A1] = - f(value) - override def traverse[F1[_], F2[_]: Applicative](value: F1[A1])( - f: [a] => F1[a] => F2[a] - ): F2[A1] = f(value) - override def traverseX[F1[_], F2[_]: Applicative, P[_]](value: F1[A1])( - f: [a] => F1[a] => F2[P[a]] - ): F2[P[A1]] = f(value) - override def foldr[F1[_], A2](value: F1[A1], init: A2)( - f: [a] => (F1[a], A2) => A2 - ): A2 = f(value, init) - - type ASplit[K1[F1[_]], F2[_]] = AList[SplitK[K1, F2]] - def asplit[K1[g[_]], G2[_]](base: AList[K1]): ASplit[K1, G2] = new ASplit[K1, G2]: - def transform[F1[_], F2[_]](value: SplitK[K1, G2][F1])( - f: [a] => F1[a] => F2[a] - ): SplitK[K1, G2][F2] = - base.transform[Compose[F1, G2], Compose[F2, G2]](value) { - nestCon[F1, F2, G2](f) - } - def traverse[F1[_], F2[_]: Applicative](value: SplitK[K1, G2][F1])( - f: [a] => F1[a] => F2[a] - ): F2[SplitK[K1, G2][Id]] = traverseX[F1, F2, Id](value)(f) - - def traverseX[F1[_], F2[_]: Applicative, P[_]](value: SplitK[K1, G2][F1])( - f: [a] => F1[a] => F2[P[a]] - ): F2[SplitK[K1, G2][P]] = - base.traverseX[Compose[F1, G2], F2, Compose[P, G2]](value) { - nestCon[F1, Compose[F2, P], G2](f) - } - def foldr[F1[_], A1](value: SplitK[K1, G2][F1], init: A1)( - f: [a] => (F1[a], A1) => A1 - ): A1 = base.foldr[Compose[F1, G2], A1](value, init) { - // This is safe because F1[G2[a]] is F1[a] - f.asInstanceOf[[a] => (F1[G2[a]], A1) => A1] - } - - type Tuple2K[A1, A2] = [F[_]] =>> Tuple.Map[(A1, A2), F] - def tuple2[A1, A2]: AList[Tuple2K[A1, A2]] = tuple[(A1, A2)] - type Tuple3K[A1, A2, A3] = [F[_]] =>> Tuple.Map[(A1, A2, A3), F] - def tuple3[A1, A2, A3]: AList[Tuple3K[A1, A2, A3]] = tuple[(A1, A2, A3)] - type Tuple4K[A1, A2, A3, A4] = [F[_]] =>> Tuple.Map[(A1, A2, A3, A4), F] - def tuple4[A1, A2, A3, A4]: AList[Tuple4K[A1, A2, A3, A4]] = tuple[(A1, A2, A3, A4)] - type Tuple5K[A1, A2, A3, A4, A5] = [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5), F] - def tuple5[A1, A2, A3, A4, A5]: AList[Tuple5K[A1, A2, A3, A4, A5]] = tuple[(A1, A2, A3, A4, A5)] - type Tuple6K[A1, A2, A3, A4, A5, A6] = [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6), F] - def tuple6[A1, A2, A3, A4, A5, A6]: AList[Tuple6K[A1, A2, A3, A4, A5, A6]] = - tuple[(A1, A2, A3, A4, A5, A6)] - type Tuple7K[A1, A2, A3, A4, A5, A6, A7] = [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6, A7), F] - def tuple7[A1, A2, A3, A4, A5, A6, A7]: AList[Tuple7K[A1, A2, A3, A4, A5, A6, A7]] = - tuple[(A1, A2, A3, A4, A5, A6, A7)] - type Tuple8K[A1, A2, A3, A4, A5, A6, A7, A8] = - [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6, A7, A8), F] - def tuple8[A1, A2, A3, A4, A5, A6, A7, A8]: AList[Tuple8K[A1, A2, A3, A4, A5, A6, A7, A8]] = - tuple[(A1, A2, A3, A4, A5, A6, A7, A8)] - type Tuple9K[A1, A2, A3, A4, A5, A6, A7, A8, A9] = - [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6, A7, A8, A9), F] - def tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9] - : AList[Tuple9K[A1, A2, A3, A4, A5, A6, A7, A8, A9]] = - tuple[(A1, A2, A3, A4, A5, A6, A7, A8, A9)] - type Tuple10K[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10] = - [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), F] - def tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10] - : AList[Tuple10K[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]] = - tuple[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)] - type Tuple11K[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11] = - [F[_]] =>> Tuple.Map[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11), F] - def tuple11[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11] - : AList[Tuple11K[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11]] = - tuple[(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)] - - def tuple[Tup <: Tuple]: AList[[F[_]] =>> Tuple.Map[Tup, F]] = - new AList[[F[_]] =>> Tuple.Map[Tup, F]]: - override def transform[F1[_], F2[_]](value: Tuple.Map[Tup, F1])( - f: [x] => F1[x] => F2[x] - ): Tuple.Map[Tup, F2] = - value match - case _: Tuple.Map[EmptyTuple, F1] => nil[Tuple.Map[Tup, F2]] - case (head: F1[x] @unchecked) *: tail => - (f(head) *: transform[F1, F2](tail.asInstanceOf)(f)) - .asInstanceOf[Tuple.Map[Tup, F2]] - - override def traverse[F1[_], F2[_]: Applicative](value: Tuple.Map[Tup, F1])( - f: [a] => F1[a] => F2[a] - ): F2[Tuple.Map[Tup, Id]] = - val F2 = summon[Applicative[F2]] - value match - case _: Tuple.Map[EmptyTuple, F1] => - F2.pure(() => nil[Tup].asInstanceOf[Tuple.Map[Tup, Id]]) - case (head: F1[x] @unchecked) *: (tail: Tuple.Map[Tail[Tup], F1] @unchecked) => - val tt = tuple[Tail[Tup]].traverse[F1, F2](tail)(f) - val g = (t: Tail[Tup]) => (h: x) => (h *: t) - F2.ap[x, Tup](F2.map(tt)(g.asInstanceOf))(f(head)).asInstanceOf[F2[Tuple.Map[Tup, Id]]] - - override def traverseX[F1[_], F2[_]: Applicative, P[_]]( - value: Tuple.Map[Tup, F1] - )( - f: [a] => F1[a] => F2[P[a]] - ): F2[Tuple.Map[Tup, P]] = - val F2 = summon[Applicative[F2]] - value match - case _: Tuple.Map[EmptyTuple, F1] => F2.pure(() => nil[Tuple.Map[Tup, P]]) - case (head: F1[x] @unchecked) *: (tail: Tuple.Map[Tail[Tup], F1] @unchecked) => - val tt = traverseX[F1, F2, P](tail.asInstanceOf)(f) - val g = (t: Tuple.Map[Tail[Tup], P]) => - (h: P[x]) => (h *: t).asInstanceOf[Tuple.Map[Tup, P]] - F2.ap[P[x], Tuple.Map[Tup, P]](F2.map(tt)(g.asInstanceOf))(f(head)) - - override def foldr[F1[_], A1](value: Tuple.Map[Tup, F1], init: A1)( - f: [a] => (F1[a], A1) => A1 - ): A1 = - value match - case _: Tuple.Map[EmptyTuple, F1] => init - case (head: F1[x] @unchecked) *: tail => - f(head, foldr[F1, A1](tail.asInstanceOf, init)(f)) - - def list[A]: AList[[F[_]] =>> List[F[A]]] = - new AList[[F[_]] =>> List[F[A]]]: - override def transform[F1[_], F2[_]](value: List[F1[A]])( - f: [x] => F1[x] => F2[x] - ): List[F2[A]] = value.map(f[A]) - - override def mapN[F1[_]: Applicative, A1](value: List[F1[A]])(f: List[Id[A]] => A1): F1[A1] = - val ap = summon[Applicative[F1]] - def loop[V](in: List[F1[A]], g: List[A] => V): F1[V] = - in match - case Nil => ap.pure(() => g(Nil)) - case x :: xs => - val h = (ts: List[A]) => (t: A) => g(t :: ts) - ap.ap(loop(xs, h))(x) - loop(value, f) - - override def foldr[F1[_], A1](value: List[F1[A]], init: A1)( - f: [a] => (F1[a], A1) => A1 - ): A1 = value.reverse.foldLeft(init)((t, m) => f(m, t)) - override def traverse[F1[_], F2[_]: Applicative](value: List[F1[A]])( - f: [a] => F1[a] => F2[a] - ): F2[List[Id[A]]] = ??? - - override def traverseX[F1[_], F2[_]: Applicative, P[_]](value: List[F1[A]])( - f: [a] => F1[a] => F2[P[a]] - ): F2[List[P[A]]] = ??? -end AList diff --git a/util-collection/src/main/scala/sbt/internal/util/INode.scala b/util-collection/src/main/scala/sbt/internal/util/INode.scala index 45bdf4158bf..a81a223f61d 100644 --- a/util-collection/src/main/scala/sbt/internal/util/INode.scala +++ b/util-collection/src/main/scala/sbt/internal/util/INode.scala @@ -10,7 +10,6 @@ package sbt.internal.util import java.lang.Runnable import java.util.concurrent.{ atomic, Executor, LinkedBlockingQueue } import atomic.{ AtomicBoolean, AtomicInteger } -import Types.Id enum EvaluationState: case New @@ -38,26 +37,19 @@ abstract class EvaluateSettings[ScopeType]: private[this] val transform: [A] => Initialize[A] => INode[A] = [A] => (fa: Initialize[A]) => fa match - case k: Keyed[s, A] @unchecked => single(getStatic(k.scopedKey), k.transform) - case a: Apply[k, A] @unchecked => - MixedNode[k, A]( - a.alist.transform[Initialize, INode](a.inputs) { transform }, - a.f, - a.alist - ) - case b: Bind[s, A] @unchecked => - new BindNode[s, A](transform(b.in), x => transform(b.f(x))) - case v: Value[A] @unchecked => constant(v.value) - case v: ValidationCapture[A] @unchecked => strictConstant(v.key: A) - case t: TransformCapture => strictConstant(t.f: A) - case o: Optional[s, A] @unchecked => + case k: Keyed[s, A] => single(getStatic(k.scopedKey), k.transform) + case u: Uniform[s, A] => UniformNode(u.inputs.map(transform[s]), u.f) + case a: Apply[k, A] => + MixedNode[k, A](TupleMapExtension.transform(a.inputs) { transform }, a.f) + case b: Bind[s, A] => BindNode[s, A](transform(b.in), x => transform(b.f(x))) + case v: Value[A] => constant(v.value) + case v: ValidationCapture[a] => strictConstant(v.key: A) + case t: TransformCapture => strictConstant(t.f: A) + case o: Optional[s, A] => o.a match case None => constant(() => o.f(None)) case Some(i) => single[s, A](transform(i), x => o.f(Some(x))) - case x if x == StaticScopes => - // can't convince scalac that StaticScopes => T == Set[Scope] - strictConstant(allScopes.asInstanceOf[A]) - // allScopes.asInstanceOf[A] + case StaticScopes => strictConstant(allScopes) private[this] lazy val roots: Seq[INode[_]] = compiledSettings.flatMap { cs => (cs.settings map { s => @@ -88,7 +80,7 @@ abstract class EvaluateSettings[ScopeType]: else ss.set(key.scope, key.key, node.get) } - private[this] lazy val getValue: [A] => INode[A] => Id[A] = [A] => (fa: INode[A]) => fa.get + private[this] lazy val getValue: [A] => INode[A] => A = [A] => (fa: INode[A]) => fa.get private[this] def submitEvaluate(node: INode[_]) = submit(node.evaluate()) @@ -210,10 +202,10 @@ abstract class EvaluateSettings[ScopeType]: private[this] def strictConstant[A1](v: A1): INode[A1] = constant(() => v) private[this] def constant[A1](f: () => A1): INode[A1] = - MixedNode[[F[_]] =>> Unit, A1]((), _ => f(), AList.empty) + MixedNode[EmptyTuple, A1](EmptyTuple, _ => f()) private[this] def single[A1, A2](in: INode[A1], f: A1 => A2): INode[A2] = - MixedNode[[F[_]] =>> F[A1], A2](in, f, AList.single[A1]) + MixedNode[Tuple1[A1], A2](Tuple1(in), { case Tuple1(a) => f(a) }) private[this] final class BindNode[A1, A2](in: INode[A1], f: A1 => INode[A2]) extends INode[A2]: protected def dependsOn: Seq[INode[_]] = in :: Nil @@ -224,10 +216,15 @@ abstract class EvaluateSettings[ScopeType]: } end BindNode - private[this] final class MixedNode[K[L[x]], A1](in: K[INode], f: K[Id] => A1, alist: AList[K]) + private[this] final class MixedNode[Tup <: Tuple, A1](in: Tuple.Map[Tup, INode], f: Tup => A1) extends INode[A1]: - protected override def dependsOn: Seq[INode[_]] = alist.toList(in) - protected override def evaluate0(): Unit = setValue(f(alist.transform(in) { getValue })) - end MixedNode + import TupleMapExtension.* + protected override def dependsOn: Seq[INode[_]] = in.iterator.toList + protected override def evaluate0(): Unit = setValue(f(in.unmap(getValue))) + + private[this] final class UniformNode[A1, A2](in: List[INode[A1]], f: List[A1] => A2) + extends INode[A2]: + protected override def dependsOn: Seq[INode[_]] = in + protected override def evaluate0(): Unit = setValue(f(in.map(_.get))) end EvaluateSettings diff --git a/util-collection/src/main/scala/sbt/internal/util/Settings.scala b/util-collection/src/main/scala/sbt/internal/util/Settings.scala index 9979db3b275..c378788a17a 100644 --- a/util-collection/src/main/scala/sbt/internal/util/Settings.scala +++ b/util-collection/src/main/scala/sbt/internal/util/Settings.scala @@ -10,6 +10,7 @@ package sbt.internal.util import Types.* import sbt.util.Show import Util.{ nil, nilSeq } +import scala.jdk.CollectionConverters.* sealed trait Settings[ScopeType]: def data: Map[ScopeType, AttributeMap] @@ -108,19 +109,16 @@ trait Init[ScopeType]: def flatMap[A1, A2](in: Initialize[A1])(f: A1 => Initialize[A2]): Initialize[A2] = Bind(f, in) def map[A1, A2](in: Initialize[A1])(f: A1 => A2): Initialize[A2] = - Apply[[F[_]] =>> F[A1], A2](f, in, AList.single[A1]) + app[Tuple1[A1], A2](Tuple1(in)) { case Tuple1(x) => f(x) } - def app[K[L[x]], A2](inputs: K[Initialize])(f: K[Id] => A2)(implicit - alist: AList[K] - ): Initialize[A2] = Apply[K, A2](f, inputs, alist) + def app[Tup <: Tuple, A2](inputs: Tuple.Map[Tup, Initialize])(f: Tup => A2): Initialize[A2] = + Apply[Tup, A2](f, inputs) def ap[A1, A2](ff: Initialize[A1 => A2])(in: Initialize[A1]): Initialize[A2] = - app[[F[_]] =>> (F[A1 => A2], F[A1]), A2]((ff, in)) { (f, a1) => - f(a1) - }(AList.tuple2[A1 => A2, A1]) + app[(A1 => A2, A1), A2]((ff, in)) { (f, a1) => f(a1) } def uniform[A1, A2](inputs: Seq[Initialize[A1]])(f: Seq[A1] => A2): Initialize[A2] = - Apply[[F[_]] =>> List[F[A1]], A2](f, inputs.toList, AList.list[A1]) + Uniform[A1, A2](f, inputs.toList) /** * The result of this initialization is the validated `key`. @@ -168,8 +166,8 @@ trait Init[ScopeType]: def empty(implicit delegates: ScopeType => Seq[ScopeType]): Settings[ScopeType] = Settings0(Map.empty, delegates) - def asTransform(s: Settings[ScopeType]): [A] => ScopedKey[A] => Id[A] = [A] => - (sk: ScopedKey[A]) => getValue(s, sk) + def asTransform(s: Settings[ScopeType]): [A] => ScopedKey[A] => A = + [A] => (sk: ScopedKey[A]) => getValue(s, sk) def getValue[T](s: Settings[ScopeType], k: ScopedKey[T]) = s.get(k.scope, k.key) getOrElse (throw new InvalidReference(k)) @@ -187,7 +185,6 @@ trait Init[ScopeType]: case r => others.add(r) } result.addAll(others) - import scala.collection.JavaConverters._ result.asScala.toVector } @@ -285,7 +282,6 @@ trait Init[ScopeType]: delegateForKey(sMap, k, delegates(k.scope), ref, selfRefOk || !isFirst) } - import scala.collection.JavaConverters._ val undefined = new java.util.ArrayList[Undefined] val result = new java.util.concurrent.ConcurrentHashMap[ScopedKey[_], Any] val backing = sMap.toSeq @@ -437,9 +433,7 @@ trait Init[ScopeType]: ): Flattened = new Flattened( key, - deps.flatMap(dep => - if (dep.key.isLocal) cmap(dep).dependencies else Seq[ScopedKey[_]](dep).toIterable - ) + deps.flatMap(dep => if (dep.key.isLocal) cmap(dep).dependencies else Seq[ScopedKey[_]](dep)) ) val empty = Map.empty[ScopedKey[_], Flattened] @@ -660,13 +654,13 @@ trait Init[ScopeType]: private[sbt] def validateKeyReferenced(g: ValidateKeyRef): ValidatedInit[A1] def evaluate(map: Settings[ScopeType]): A1 - def zip[A2](o: Initialize[A2]): Initialize[(A1, A2)] = zipTupled(o)(idFun) + def zip[A2](o: Initialize[A2]): Initialize[(A1, A2)] = zipTupled(o)(identity) def zipWith[A2, U](o: Initialize[A2])(f: (A1, A2) => U): Initialize[U] = zipTupled(o)(f.tupled) private[this] def zipTupled[A2, U](o: Initialize[A2])(f: ((A1, A2)) => U): Initialize[U] = - Apply[[F[_]] =>> Tuple.Map[(A1, A2), F], U](f, (this, o), AList.tuple2[A1, A2]) + Apply[(A1, A2), U](f, (this, o)) /** A fold on the static attributes of this and nested Initializes. */ private[sbt] def processAttributes[S](init: S)(f: (S, AttributeMap) => S): S @@ -677,10 +671,10 @@ trait Init[ScopeType]: final class JoinInitSeq[A1](s: Seq[Initialize[A1]]): def joinWith[A2](f: Seq[A1] => A2): Initialize[A2] = uniform(s)(f) - def join: Initialize[Seq[A1]] = uniform(s)(idFun) + def join: Initialize[Seq[A1]] = uniform(s)(identity) end JoinInitSeq - def join[A1](inits: Seq[Initialize[A1]]): Initialize[Seq[A1]] = uniform(inits)(idFun) + def join[A1](inits: Seq[Initialize[A1]]): Initialize[Seq[A1]] = uniform(inits)(identity) def joinAny[F[_]]: [a] => Seq[Initialize[F[a]]] => Initialize[Seq[F[Any]]] = [a] => (inits: Seq[Initialize[F[a]]]) => join(inits.asInstanceOf[Seq[Initialize[F[Any]]]]) @@ -805,7 +799,7 @@ trait Init[ScopeType]: (fa: Initialize[A]) => (fa.mapReferenced(g)) private[this] def mapConstantK(g: MapConstant): [A] => Initialize[A] => Initialize[A] = [A] => (fa: Initialize[A]) => (fa.mapConstant(g)) - private[this] def evaluateK(g: Settings[ScopeType]): [A] => Initialize[A] => Id[A] = [A] => + private[this] def evaluateK(g: Settings[ScopeType]): [A] => Initialize[A] => A = [A] => (fa: Initialize[A]) => (fa.evaluate(g)) private[this] def deps(ls: Seq[Initialize[_]]): Seq[ScopedKey[_]] = ls.flatMap(_.dependencies) @@ -847,7 +841,7 @@ trait Init[ScopeType]: * @tparam A1 the type of both the value this `Initialize` defines and the type of the associated `ScopedKey`. */ trait KeyedInitialize[A1] extends Keyed[A1, A1]: - final val transform = idFun[A1] + final val transform = identity[A1] end KeyedInitialize private[sbt] final class TransformCapture(val f: [x] => Initialize[x] => Initialize[x]) @@ -957,34 +951,60 @@ trait Init[ScopeType]: init end StaticScopes - private[sbt] final class Apply[K[F[x]], A1]( - val f: K[Id] => A1, - val inputs: K[Initialize], - val alist: AList[K] + private[sbt] final class Uniform[A1, A2](val f: Seq[A1] => A2, val inputs: List[Initialize[A1]]) + extends Initialize[A2]: + override def dependencies: Seq[ScopedKey[_]] = deps(inputs) + override def mapReferenced(g: MapScoped): Initialize[A2] = + Uniform(f, inputs.map(_.mapReferenced(g))) + override def mapConstant(g: MapConstant): Initialize[A2] = + Uniform(f, inputs.map(_.mapConstant(g))) + override def apply[A3](g: A2 => A3): Initialize[A3] = Uniform(g.compose(f), inputs) + override def evaluate(ss: Settings[ScopeType]): A2 = f(inputs.map(_.evaluate(ss))) + + override def validateKeyReferenced(g: ValidateKeyRef): ValidatedInit[A2] = + val tx = inputs.map(_.validateKeyReferenced(g)) + val undefs = tx.flatMap(_.left.toSeq.flatten) + if undefs.isEmpty then Right(Uniform(f, tx.map(_.right.get))) + else Left(undefs) + + private[sbt] override def processAttributes[A2](init: A2)(f: (A2, AttributeMap) => A2): A2 = + inputs.foldLeft(init)((v, i) => i.processAttributes(v)(f)) + + /* private[sbt] final class Mapped[A1, A2](f: A1 => A2, input: Initialize[A1]) extends Initialize[A1]: + override def dependencies: Seq[ScopedKey[_]] = deps(Seq(inputs)) + override def mapReferenced(g: MapScoped): Initialize[A2] = Mapped(f, input.mapReferenced(g)) + override def mapConstant(g: MapConstant): Initialize[A2] = Mapped(f, input.mapConstant(g)) + override def apply[A3](g: A2 => A3): Initialize[A3] = Mapped(g.compose(f), input) + override def evaluate(ss: Settings[ScopeType]): A2 = f(input.evaluate(ss)) + override def validateKeyReferenced(g: ValidateKeyRef): ValidatedInit[A1] = input.validateKeyReferenced(g) + private[sbt] override def processAttributes[A2](init: A2)(f: (A2, AttributeMap) => A2): A2 = + input.processAttributes(init)(f) */ + + private[sbt] final class Apply[Tup <: Tuple, A1]( + val f: Tup => A1, + val inputs: Tuple.Map[Tup, Initialize] ) extends Initialize[A1]: - override def dependencies: Seq[ScopedKey[_]] = deps(alist.toList(inputs)) - override def mapReferenced(g: MapScoped): Initialize[A1] = mapInputs(mapReferencedK(g)) - override def mapConstant(g: MapConstant): Initialize[A1] = mapInputs(mapConstantK(g)) + import sbt.internal.util.TupleMapExtension.* - override def apply[A2](g: A1 => A2): Initialize[A2] = Apply(g compose f, inputs, alist) + override def dependencies: Seq[ScopedKey[_]] = deps(inputs.iterator.toList) + override def mapReferenced(g: MapScoped): Initialize[A1] = + Apply(f, inputs.transform(mapReferencedK(g))) + override def mapConstant(g: MapConstant): Initialize[A1] = + Apply(f, inputs.transform(mapConstantK(g))) - def mapInputs(g: [a] => Initialize[a] => Initialize[a]): Initialize[A1] = - Apply(f, alist.transform(inputs) { g }, alist) + override def apply[A2](g: A1 => A2): Initialize[A2] = Apply(g compose f, inputs) - override def evaluate(ss: Settings[ScopeType]): A1 = - f(alist.transform(inputs) { evaluateK(ss) }) + override def evaluate(ss: Settings[ScopeType]): A1 = f(inputs.unmap(evaluateK(ss))) override def validateKeyReferenced(g: ValidateKeyRef): ValidatedInit[A1] = - val tx = alist.transform(inputs) { validateKeyReferencedK(g) } - val undefs = alist.toList(tx).flatMap(_.left.toSeq.flatten) + val tx: Tuple.Map[Tup, ValidatedInit] = inputs.transform(validateKeyReferencedK(g)) + val undefs = tx.iterator.flatMap(_.left.toSeq.flatten) val get = [A] => (fa: ValidatedInit[A]) => (fa.right.get) - if undefs.isEmpty then Right(Apply(f, alist.transform(tx) { get }, alist)) - else Left(undefs) + if undefs.isEmpty then Right(Apply(f, tx.transform(get))) + else Left(undefs.toSeq) private[sbt] override def processAttributes[A2](init: A2)(f: (A2, AttributeMap) => A2): A2 = - alist.toList(inputs).foldLeft(init) { (v, i) => - i.processAttributes(v)(f) - } + inputs.iterator.toList.foldLeft(init) { (v, i) => i.processAttributes(v)(f) } end Apply private def remove[A](s: Seq[A], v: A) = s.filterNot(_ == v) diff --git a/util-collection/src/main/scala/sbt/internal/util/TupleMapExtension.scala b/util-collection/src/main/scala/sbt/internal/util/TupleMapExtension.scala new file mode 100644 index 00000000000..f86508ef6f1 --- /dev/null +++ b/util-collection/src/main/scala/sbt/internal/util/TupleMapExtension.scala @@ -0,0 +1,32 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt.internal +package util + +import sbt.util.Applicative + +object TupleMapExtension: + extension [Tup <: Tuple, F1[_]](tuple: Tuple.Map[Tup, F1]) + def iterator: Iterator[F1[Any]] = tuple.productIterator.asInstanceOf[Iterator[F1[Any]]] + + def unmap(f: [a] => F1[a] => a): Tup = + Tuple.fromArray(tuple.iterator.map(f(_)).toArray).asInstanceOf[Tup] + + def transform[F2[_]](f: [a] => F1[a] => F2[a]): Tuple.Map[Tup, F2] = + Tuple.fromArray(tuple.iterator.map(f(_)).toArray).asInstanceOf[Tuple.Map[Tup, F2]] + + def traverse[F2[_]](f: [a] => F1[a] => F2[a])(using app: Applicative[F2]): F2[Tup] = + val fxs: F2[List[Any]] = tuple.iterator + .foldRight[F2[List[Any]]](app.pure(() => Nil))((x, xs) => + app.map(app.product(f(x), xs))((h, t) => h :: t) + ) + app.map(fxs)(xs => Tuple.fromArray(xs.toArray).asInstanceOf[Tup]) + + def mapN[A1](f: Tup => A1)(using app: Applicative[F1]): F1[A1] = + app.map(tuple.traverse[F1]([a] => (f: F1[a]) => f))(f) +end TupleMapExtension diff --git a/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala b/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala index 89f3807f1af..28ac50dd7e6 100644 --- a/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala +++ b/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala @@ -20,11 +20,6 @@ trait TypeFunctions: type Compose[F1[_], F2[_]] = [a] =>> F1[F2[a]] - /** - * Example: calling `SplitK[K1, Task]` returns the type lambda `F[a] => K1[F[Task[a]]`. - */ - type SplitK[K1[F1[_]], F2[_]] = [f[_]] =>> K1[Compose[f, F2]] - sealed trait ∙[A[_], B[_]] { type l[T] = A[B[T]] } private type AnyLeft[A] = Left[A, Nothing] private type AnyRight[A] = Right[Nothing, A] diff --git a/util-collection/src/test/scala/AListTest.scala b/util-collection/src/test/scala/AListTest.scala deleted file mode 100644 index 993fa7e119d..00000000000 --- a/util-collection/src/test/scala/AListTest.scala +++ /dev/null @@ -1,22 +0,0 @@ -package sbt.internal - -import verify.BasicTestSuite -import sbt.internal.util.AList - -object AListTest extends BasicTestSuite: - val t1 = ((Option(1), Option("foo"))) - - test("tuple.mapN") { - val tuple = t1 - val f = (arg: (Int, String)) => arg._1.toString + "|" + arg._2 - val actual = AList.tuple[(Int, String)].mapN[Option, String](tuple)(f) - assert(actual == Option("1|foo")) - } - - test("list.mapN") { - val list = List(Option(1), Option(2), Option(3)) - val f = (arg: List[Int]) => arg.mkString("|") - val actual = AList.list[Int].mapN[Option, String](list)(f) - assert(actual == Some("1|2|3")) - } -end AListTest diff --git a/util-collection/src/test/scala/TupleMapExtensionTest.scala b/util-collection/src/test/scala/TupleMapExtensionTest.scala new file mode 100644 index 00000000000..6665d9cad11 --- /dev/null +++ b/util-collection/src/test/scala/TupleMapExtensionTest.scala @@ -0,0 +1,13 @@ +package sbt.internal.util + +import verify.BasicTestSuite +import sbt.internal.util.TupleMapExtension.* + +object TupleMapExtensionTest extends BasicTestSuite: + val tuple: Tuple.Map[(Int, String), Option] = ((Option(1), Option("foo"))) + + test("tuple.mapN") { + val f = (arg: (Int, String)) => arg._1.toString + "|" + arg._2 + val actual = tuple.mapN[String](f) + assert(actual == Option("1|foo")) + }