Remove AList

This commit is contained in:
Adrien Piquerez 2023-12-13 14:01:57 +01:00
parent 8950b92d33
commit a15fb91c5c
20 changed files with 278 additions and 518 deletions

View File

@ -4,11 +4,9 @@ package util
package appmacro package appmacro
import scala.collection.mutable.ListBuffer import scala.collection.mutable.ListBuffer
import scala.reflect.TypeTest
import scala.quoted.* import scala.quoted.*
import sbt.util.Applicative import sbt.util.Applicative
import sbt.util.Monad import sbt.util.Monad
import Types.Id
/** /**
* Implementation of a macro that provides a direct syntax for applicative functors and monads. It * Implementation of a macro that provides a direct syntax for applicative functors and monads. It
@ -237,13 +235,9 @@ trait Cont:
case '[inputTypeTpe] => case '[inputTypeTpe] =>
'{ '{
given Applicative[F] = $instanceExpr given Applicative[F] = $instanceExpr
AList import TupleMapExtension.*
.tuple[inputTypeTpe & Tuple] ${ br.tupleExpr.asInstanceOf[Expr[Tuple.Map[inputTypeTpe & Tuple, F]]] }
.mapN[F, A1](${ .mapN(${ lambda.asExprOf[inputTypeTpe & Tuple => A1] })
br.tupleExpr.asInstanceOf[Expr[Tuple.Map[inputTypeTpe & Tuple, F]]]
})(
${ lambda.asExprOf[Tuple.Map[inputTypeTpe & Tuple, Id] => A1] }
)
} }
eitherTree match eitherTree match

View File

@ -9,8 +9,9 @@ package sbt
import scala.annotation.targetName import scala.annotation.targetName
import sbt.internal.util.Types._ import sbt.internal.util.Types.*
import sbt.internal.util.{ ~>, AList, AttributeKey, Settings, SourcePosition } import sbt.internal.util.{ ~>, AttributeKey, Settings, SourcePosition }
import sbt.internal.util.TupleMapExtension.*
import sbt.util.OptJsonWriter import sbt.util.OptJsonWriter
import sbt.ConcurrentRestrictions.Tag import sbt.ConcurrentRestrictions.Tag
import sbt.Def.{ Initialize, ScopedKey, Setting, setting } import sbt.Def.{ Initialize, ScopedKey, Setting, setting }
@ -354,7 +355,7 @@ object Scoped:
* one setting in order to define another setting. * one setting in order to define another setting.
* @return currently bound value wrapped in `Initialize[Some[T]]`, or `Initialize[None]` if unbound. * @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. * 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) { def ? : Initialize[Task[Option[A1]]] = Def.optional(scopedKey) {
case None => mktask { None } 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)) 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: _*)) .apply(deps => nop.dependsOn(deps: _*))
} }
sealed abstract class RichTaskables[K[+L[x]]](final val keys: K[Taskable])(using sealed abstract class RichTaskables[Tup <: Tuple](final val keys: Tuple.Map[Tup, Taskable]):
a: AList[K]
):
type App[T] = Initialize[Task[T]] type App[T] = Initialize[Task[T]]
@ -544,90 +543,91 @@ object Scoped:
type Fun[M[_], Ret] type Fun[M[_], Ret]
/** Convert the higher-kinded function to a Function1. For tuples that means call `.tupled`. */ /** 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) { private def convert[Ret](f: Fun[Id, Ret]): Tup => Ret = convertK(f).asInstanceOf
[A] => (fa: Taskable[A]) => fa.toTask
}
private[this] def onTasks[A1](f: K[Task] => Task[A1]): App[A1] = private[this] val inputs: Tuple.Map[Tup, App] =
Def.app[SplitK[K, Task], Task[A1]](inputs)(f)(AList.asplit[K, Task](a)) keys.transform { [A] => (fa: Taskable[A]) => fa.toTask }
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 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 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 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 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 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 mapFailure[T](f: Seq[Incomplete] => T): App[T] = onTasks(_.mapFailure(f))
end RichTaskables end RichTaskables
// format: off // format: off
type ST[X] = Taskable[X] 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 type Fun[M[_], Ret] = M[A1] => Ret
def identityMap = mapN(identity) 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 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 type Fun[M[_], Ret] = (M[A], M[B]) => Ret
def identityMap = mapN(mkTuple2) 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 type Fun[M[_], Ret] = (M[A], M[B], M[C]) => Ret
def identityMap = mapN(mkTuple3) 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 type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D]) => Ret
def identityMap = mapN(mkTuple4) 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 type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E]) => Ret
def identityMap = mapN(mkTuple5) 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 type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F]) => Ret
def identityMap = mapN(mkTuple6) 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 type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G]) => Ret
def identityMap = mapN(mkTuple7) 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 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) 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 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) 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 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) 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 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) 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) 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) 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])): 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) def identity = apply(mkTuple2)
end Apply2 end Apply2
final class Apply3[A, B, C](t3: (Initialize[A], Initialize[B], Initialize[C])): 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) def identity = apply(mkTuple3)
end Apply3 end Apply3
final class Apply4[A, B, C, D](t4: (Initialize[A], Initialize[B], Initialize[C], Initialize[D])): 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) def identity = apply(mkTuple4)
end Apply4 end Apply4
final class Apply5[A, B, C, D, E](t5: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E])): 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) def identity = apply(mkTuple5)
end Apply5 end Apply5
final class Apply6[A, B, C, D, E, F](t6: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F])): 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) def identity = apply(mkTuple6)
end Apply6 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])): 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) def identity = apply(mkTuple7)
end Apply7 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])): 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) def identity = apply(mkTuple8)
end Apply8 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])): 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) def identity = apply(mkTuple9)
end Apply9 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])): 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) def identity = apply(mkTuple10)
end Apply10 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])): 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) def identity = apply(mkTuple11)
end Apply11 end Apply11
@ -713,7 +713,7 @@ trait TupleSyntax:
// this is the least painful arrangement I came up with // this is the least painful arrangement I came up with
type ST[T] = Taskable[T] 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 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 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) 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]): class TupleWrap[Tup <: Tuple](value: Tuple.Map[Tup, Taskable]):
type InitTask[A2] = Initialize[Task[A2]] type InitTask[A2] = Initialize[Task[A2]]
lazy val alist = AList.tuple[Tup] lazy val initTasks = value.transform[InitTask]([a] => (t: Taskable[a]) => t.toTask)
lazy val initTasks =
alist.transform[Taskable, InitTask](value)([a] => (t: Taskable[a]) => t.toTask)
def mapN[A1](f: Tup => A1): Def.Initialize[Task[A1]] = def mapN[A1](f: Tup => A1): Def.Initialize[Task[A1]] =
import std.FullInstance.initializeTaskMonad initTasks.mapN[A1](f)(using std.FullInstance.initializeTaskMonad)
alist.mapN[InitTask, A1](initTasks)(f.asInstanceOf[Tuple.Map[Tup, Id] => A1])

View File

@ -10,8 +10,7 @@ package std
import Def.Initialize import Def.Initialize
import sbt.util.{ Applicative, Monad } import sbt.util.{ Applicative, Monad }
import sbt.internal.util.AList import sbt.internal.util.Types.{ const, Compose }
import sbt.internal.util.Types.{ const, Id, Compose, idFun }
import sbt.internal.util.complete.{ DefaultParsers, Parser } import sbt.internal.util.complete.{ DefaultParsers, Parser }
object InitializeInstance: object InitializeInstance:
@ -80,33 +79,19 @@ object FullInstance:
FullInstance.flatten[A1](in) FullInstance.flatten[A1](in)
def flatten[A1](in: Initialize[Task[Initialize[Task[A1]]]]): Initialize[Task[A1]] = def flatten[A1](in: Initialize[Task[Initialize[Task[A1]]]]): Initialize[Task[A1]] =
type K[L[x]] = type Tup = (Task[Initialize[Task[A1]]], Task[SS], [a] => Initialize[a] => Initialize[a])
AList.Tuple3K[Task[Initialize[Task[A1]]], Task[SS], [a] => Initialize[a] => Initialize[a]][ Def.app[Tup, Task[A1]]((in, settingsData, Def.capturedTransformations)) {
L
]
Def.app[K, Task[A1]]((in, settingsData, Def.capturedTransformations)) {
case (a: Task[Initialize[Task[A1]]], data: Task[SS], f) => case (a: Task[Initialize[Task[A1]]], data: Task[SS], f) =>
import TaskExtra.multT2Task TaskExtra.multT2Task((a, data)).flatMapN { case (a, d) => f(a) evaluate d }
(a, data).flatMapN { case (a, d) => f(a) evaluate d } }
}(AList.tuple3[Task[Initialize[Task[A1]]], Task[SS], [a] => Initialize[a] => Initialize[a]])
def flattenFun[A1, A2]( def flattenFun[A1, A2](
in: Initialize[Task[A1 => Initialize[Task[A2]]]] in: Initialize[Task[A1 => Initialize[Task[A2]]]]
): Initialize[A1 => Task[A2]] = ): Initialize[A1 => Task[A2]] =
type K[L[x]] = type Tup = (Task[A1 => Initialize[Task[A2]]], Task[SS], [a] => Initialize[a] => Initialize[a])
AList.Tuple3K[Task[A1 => Initialize[Task[A2]]], Task[SS], [a] => Initialize[a] => Initialize[ Def.app[Tup, A1 => Task[A2]]((in, settingsData, Def.capturedTransformations)) {
a case (a: Task[A1 => Initialize[Task[A2]]] @unchecked, data: Task[SS] @unchecked, f) =>
]][L] (s: A1) => TaskExtra.multT2Task((a, data)).flatMapN { case (af, d) => f(af(s)) evaluate d }
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
]]
)
end FullInstance end FullInstance

View File

@ -10,7 +10,7 @@ package std
import Def.{ Initialize, Setting } import Def.{ Initialize, Setting }
import sbt.util.{ Applicative, Monad } 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.{ import sbt.internal.util.appmacro.{
Cont, Cont,
ContextUtil, ContextUtil,
@ -21,7 +21,7 @@ import sbt.internal.util.appmacro.{
// MonadInstance // MonadInstance
} }
// import Instance.Transform // import Instance.Transform
import sbt.internal.util.{ AList, LinePosition, NoPosition, SourcePosition, ~> } import sbt.internal.util.{ LinePosition, NoPosition, SourcePosition, ~> }
import language.experimental.macros import language.experimental.macros
import scala.annotation.tailrec import scala.annotation.tailrec

View File

@ -9,7 +9,6 @@ package sbt.test
import sbt._ import sbt._
import sbt.Def.Initialize import sbt.Def.Initialize
import sbt.internal.util.AList
import sbt.internal.util.Types.Id import sbt.internal.util.Types.Id
object TupleSyntaxTest: object TupleSyntaxTest:

View File

@ -121,8 +121,6 @@ trait Import {
val Tracked = sbt.util.Tracked val Tracked = sbt.util.Tracked
// sbt.internal.util // 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 AbstractRMap[K[_], V[_]] = sbt.internal.util.AbstractRMap[K, V]
type AlreadyHandledException = sbt.internal.util.AlreadyHandledException type AlreadyHandledException = sbt.internal.util.AlreadyHandledException
val AttributeEntry = sbt.internal.util.AttributeEntry val AttributeEntry = sbt.internal.util.AttributeEntry

View File

@ -8,8 +8,8 @@
package sbt package sbt
import sbt.internal.Action import sbt.internal.Action
import sbt.internal.util.Types._ import sbt.internal.util.Types.const
import sbt.internal.util.{ ~>, AList, AttributeKey, AttributeMap } import sbt.internal.util.{ ~>, AttributeKey, AttributeMap }
import ConcurrentRestrictions.{ Tag, TagMap, tagsKey } import ConcurrentRestrictions.{ Tag, TagMap, tagsKey }
import sbt.util.Monad 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 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 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 end Task
/** /**

View File

@ -8,8 +8,6 @@
package sbt package sbt
package internal package internal
import sbt.internal.util.AList
// Action, Task, and Info are intentionally invariant in their type parameter. // Action, Task, and Info are intentionally invariant in their type parameter.
// Various natural transformations used, such as PMap, require invariant type constructors for correctness // 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 // 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. */ /** 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) // 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. */ /** Computes another task to evaluate based on results from evaluating other tasks. */
case FlatMapped[A, K[+F[_]]]( case FlatMapped[A, Tup <: Tuple](
in: K[Task], in: Tuple.Map[Tup, Task],
f: K[Result] => Task[A], f: Tuple.Map[Tup, Result] => Task[A]
alist: AList[K],
) extends Action[A] ) extends Action[A]
// private[sbt] def mapTask(g: Task ~> Task) = // private[sbt] def mapTask(g: Task ~> Task) =
// FlatMapped[A, K](alist.transform(in, g), g.fn[A] compose f, alist) // 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]( private[sbt] def asFlatMapped[A1, A2](
s: Action.Selected[A1, A2] s: Action.Selected[A1, A2]
): Action.FlatMapped[A2, [F[_]] =>> Tuple1[F[Either[A1, A2]]]] = ): Action.FlatMapped[A2, Tuple1[Either[A1, A2]]] =
val alist = AList.tuple[Tuple1[Either[A1, A2]]]
val f: Either[A1, A2] => Task[A2] = { val f: Either[A1, A2] => Task[A2] = {
case Right(b) => task(b) case Right(b) => task(b)
case Left(a) => singleInputTask(s.fin).map(_(a)) 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), Tuple1(s.fab),
{ case Tuple1(r) => f.compose(successM)(r) }, { case Tuple1(r) => f.compose(successM)(r) },
alist,
) )
end Action end Action

View File

@ -10,17 +10,17 @@ package std
import scala.sys.process.{ BasicIO, ProcessIO, ProcessBuilder } import scala.sys.process.{ BasicIO, ProcessIO, ProcessBuilder }
import sbt.internal.util.{ AList, AttributeMap } import sbt.internal.util.AttributeMap
import sbt.internal.util.Types._ import sbt.internal.util.TupleMapExtension.*
import java.io.{ BufferedInputStream, BufferedReader, File, InputStream } import java.io.{ BufferedInputStream, BufferedReader, File, InputStream }
import sbt.io.IO import sbt.io.IO
import sbt.internal.Action import sbt.internal.Action
sealed trait MultiInTask[K[F[_]]] { sealed trait MultiInTask[Tup <: Tuple] {
def flatMapN[A](f: K[Id] => Task[A]): Task[A] def flatMapN[A](f: Tup => Task[A]): Task[A]
def flatMapR[A](f: K[Result] => Task[A]): Task[A] def flatMapR[A](f: Tuple.Map[Tup, Result] => Task[A]): Task[A]
def mapN[A](f: K[Id] => A): Task[A] def mapN[A](f: Tup => A): Task[A]
def mapR[A](f: K[Result] => 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 flatFailure[A](f: Seq[Incomplete] => Task[A]): Task[A]
def mapFailure[A](f: Seq[Incomplete] => 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 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] { 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 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 } 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) def reduced(f: (S, S) => S): Task[S] = TaskExtra.reduced(in.toIndexedSeq, f)
} }
final implicit def multT2Task[A1, A2]( final implicit def multT2Task[A1, A2](in: (Task[A1], Task[A2])): MultiInTask[(A1, A2)] =
in: (Task[A1], Task[A2]) multInputTask[(A1, A2)](in)
): 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)
given multT2TaskConv[A1, A2] given multT2TaskConv[A1, A2]: Conversion[(Task[A1], Task[A2]), MultiInTask[(A1, A2)]] =
: Conversion[(Task[A1], Task[A2]), MultiInTask[[F[_]] =>> Tuple.Map[(A1, A2), F]]] =
multT2Task(_) multT2Task(_)
final implicit def multInputTask[K[+F[_]]: AList](tasks: K[Task]): MultiInTask[K] = final implicit def multInputTask[Tup <: Tuple](tasks: Tuple.Map[Tup, Task]): MultiInTask[Tup] =
new MultiInTask[K]: new MultiInTask[Tup]:
override def flatMapN[A](f: K[Id] => Task[A]): Task[A] = override def flatMapN[A](f: Tup => Task[A]): Task[A] =
Task(Info(), Action.FlatMapped[A, K](tasks, f compose allM, AList[K])) Task(Info(), Action.FlatMapped(tasks, f.compose(allM)))
override def flatMapR[A](f: K[Result] => Task[A]): Task[A] = override def flatMapR[A](f: Tuple.Map[Tup, Result] => Task[A]): Task[A] =
Task(Info(), Action.FlatMapped[A, K](tasks, f, AList[K])) Task(Info(), Action.FlatMapped(tasks, f))
override def mapN[A](f: K[Id] => A): Task[A] = override def mapN[A](f: Tup => A): Task[A] =
Task(Info(), Action.Mapped[A, K](tasks, f compose allM, AList[K])) Task(Info(), Action.Mapped(tasks, f.compose(allM)))
override def mapR[A](f: K[Result] => A): Task[A] = override def mapR[A](f: Tuple.Map[Tup, Result] => A): Task[A] =
Task(Info(), Action.Mapped[A, K](tasks, f, AList[K])) Task(Info(), Action.Mapped(tasks, f))
override def flatFailure[A](f: Seq[Incomplete] => Task[A]): Task[A] = 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] = 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] = final implicit def singleInputTask[S](in: Task[S]): SingleInTask[S] =
new SingleInTask[S]: new SingleInTask[S]:
// type K[L[x]] = L[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 failure: Task[Incomplete] = mapFailure(identity)
def result: Task[Result[S]] = mapR(idFun) def result: Task[Result[S]] = mapR(identity)
private def newInfo[A]: Info[A] = TaskExtra.newInfo(in.info) private def newInfo[A]: Info[A] = TaskExtra.newInfo(in.info)
override def flatMapR[A](f: Result[S] => Task[A]): Task[A] = override def flatMapR[A](f: Result[S] => Task[A]): Task[A] =
Task( Task(
newInfo, newInfo,
Action.FlatMapped[A, [F[_]] =>> Tuple.Map[Tuple1[S], F]]( Action.FlatMapped[A, Tuple1[S]](Tuple1(in), { case Tuple1(a) => f(a) })
AList.toTuple(in),
AList.fromTuple(f),
alist,
)
) )
override def mapR[A](f: Result[S] => A): Task[A] = override def mapR[A](f: Result[S] => A): Task[A] =
Task( Task(
newInfo, newInfo,
Action.Mapped[A, [F[_]] =>> Tuple.Map[Tuple1[S], F]]( Action.Mapped[A, Tuple1[S]](Tuple1(in), { case Tuple1(a) => f(a) })
AList.toTuple(in),
AList.fromTuple(f),
alist,
)
) )
override def dependsOn(tasks: Task[_]*): Task[S] = Task(newInfo, Action.DependsOn(in, tasks)) 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 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 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 andFinally(fin: => Unit): Task[S] = mapR(x => Result.tryValue[S]({ fin; x }))
def doFinally(t: Task[Unit]): Task[S] = 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] = 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[(A1, A1)]((a, b)).mapN(f.tupled)
multInputTask[[F[_]] =>> Tuple.Map[(A1, A1), F]]((a, b)) mapN f.tupled
def anyFailM[K[F[_]]: AList]: K[Result] => Seq[Incomplete] = in => { def anyFailM[Tup <: Tuple]: Tuple.Map[Tup, Result] => Seq[Incomplete] = in => {
val incs = failuresM[K](AList[K])(in) val incs = failuresM[Tup](in)
if incs.isEmpty then expectedFailure if incs.isEmpty then expectedFailure
else incs else incs
} }
@ -321,13 +307,13 @@ object TaskExtra extends TaskExtra {
case Result.Value(a) => a case Result.Value(a) => a
} }
def allM[K[F[_]]: AList]: K[Result] => K[Id] = in => { def allM[Tup <: Tuple]: Tuple.Map[Tup, Result] => Tup = in => {
val incs = failuresM[K](AList[K])(in) val incs = failuresM[Tup](in)
if incs.isEmpty then AList[K].transform[Result, Id](in)(Result.tryValue) // .asInstanceOf if incs.isEmpty then in.unmap(Result.tryValue)
else throw incompleteDeps(incs) else throw incompleteDeps(incs)
} }
def failuresM[K[F[_]]: AList]: K[Result] => Seq[Incomplete] = x => def failuresM[Tup <: Tuple]: Tuple.Map[Tup, Result] => Seq[Incomplete] = x =>
failures[Any](AList[K].toList(x)) failures(x.iterator.toList)
def all[D](in: Seq[Result[D]]): Seq[D] = { def all[D](in: Seq[Result[D]]): Seq[D] = {
val incs = failures(in) val incs = failures(in)

View File

@ -9,8 +9,8 @@ package sbt
package std package std
import sbt.internal.Action import sbt.internal.Action
import sbt.internal.util.Types._ import sbt.internal.util.{ ~>, DelegatingPMap, RMap }
import sbt.internal.util.{ ~>, AList, DelegatingPMap, RMap } import sbt.internal.util.TupleMapExtension.*
import TaskExtra.{ all, existToAny } import TaskExtra.{ all, existToAny }
import sbt.internal.util.Types.* import sbt.internal.util.Types.*
@ -49,15 +49,12 @@ object Transform:
new NodeView: new NodeView:
import Action.* import Action.*
def apply[T](t: TaskId[T]): Node[T] = pre(t).work match def apply[T](t: TaskId[T]): Node[T] = pre(t).work match
case Pure(eval, _) => uniform(Nil)(_ => Right(eval())) 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: Mapped[a, t] => toNode(m.in)(right[a].compose(m.f))
case m: FlatMapped[a, k] => case m: FlatMapped[a, t] => toNode(m.in)(left[Task[a]].compose(m.f))
toNode[a, k](m.in)(left[Task[a]] compose m.f)(m.alist) // (m.alist)
case s: Selected[a1, a2] => case s: Selected[a1, a2] =>
val m = Action.asFlatMapped[a1, a2](s) val m = Action.asFlatMapped[a1, a2](s)
toNode[a2, [F[_]] =>> Tuple1[F[Either[a1, a2]]]](m.in)(left[Task[a2]] compose m.f)( toNode(m.in)(left[Task[a2]].compose(m.f))
m.alist
)
case DependsOn(in, deps) => uniform(existToAny(deps))(const(Left(in)) compose all) case DependsOn(in, deps) => uniform(existToAny(deps))(const(Left(in)) compose all)
case Join(in, f) => uniform(in)(f) case Join(in, f) => uniform(in)(f)
@ -68,15 +65,19 @@ object Transform:
def uniform[A1, D](tasks: Seq[Task[D]])( def uniform[A1, D](tasks: Seq[Task[D]])(
f: Seq[Result[D]] => Either[Task[A1], A1] f: Seq[Result[D]] => Either[Task[A1], A1]
): Node[A1] = ): Node[A1] =
toNode[A1, [F[_]] =>> List[F[D]]](tasks.toList)(f)(AList.list[D])
def toNode[A1, K1[F[_]]: AList](
inputs: K1[TaskId]
)(f: K1[Result] => Either[Task[A1], A1]): Node[A1] =
new Node[A1]: new Node[A1]:
type K[F[_]] = K1[F] type Inputs = Seq[Result[D]]
val in = inputs def dependencies: List[TaskId[D]] = tasks.toList
lazy val alist: AList[K] = AList[K] def computeInputs(f: [a] => (x: TaskId[a]) => Result[a]): Inputs = tasks.map(f[D])
def work(results: K[Result]) = f(results) def work(inputs: Inputs) = f(inputs)
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 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 end Transform

View File

@ -7,15 +7,11 @@
package sbt package sbt
import sbt.internal.util.AList
object Test extends std.TaskExtra: object Test extends std.TaskExtra:
def t2[A1, A2](a1: Task[A1], a2: Task[A2]) = def t2[A1, A2](a1: Task[A1], a2: Task[A2]) =
given AList[[F[_]] =>> Tuple.Map[(A1, A2), F]] = AList.tuple[(A1, A2)] multInputTask[(A1, A2)]((a1, a2))
multInputTask[[F[_]] =>> Tuple.Map[(A1, A2), F]]((a1, a2))
def t3[A1, A2, A3](a1: Task[A1], a2: Task[A2], a3: Task[A3]) = 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[(A1, A2, A3)]((a1, a2, a3))
multInputTask[[F[_]] =>> Tuple.Map[(A1, A2, A3), F]]((a1, a2, a3))
val a = task(3) val a = task(3)
val b = task[Boolean](sys.error("test")) val b = task[Boolean](sys.error("test"))

View File

@ -11,14 +11,13 @@ import java.util.concurrent.ExecutionException
import sbt.internal.util.ErrorHandling.wideConvert import sbt.internal.util.ErrorHandling.wideConvert
import sbt.internal.util.{ DelegatingPMap, IDSet, PMap, RMap, ~> } 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 sbt.internal.util.Util.nilSeq
import scala.annotation.tailrec import scala.annotation.tailrec
import scala.collection.mutable import scala.collection.mutable
import scala.jdk.CollectionConverters.* import scala.jdk.CollectionConverters.*
import mutable.Map import mutable.Map
import sbt.internal.util.AList
private[sbt] object Execute { private[sbt] object Execute {
def taskMap[A]: Map[TaskId[?], A] = (new java.util.IdentityHashMap[TaskId[?], A]).asScala 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 { private[sbt] def completed(p: => Unit): Completed = new Completed {
def process(): Unit = p 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 = def config(checkCycles: Boolean, overwriteNode: Incomplete => Boolean = const(false)): Config =
new Config(checkCycles, overwriteNode) new Config(checkCycles, overwriteNode)
@ -280,8 +279,7 @@ private[sbt] final class Execute(
/** Send the work for this node to the provided Strategy. */ /** Send the work for this node to the provided Strategy. */
def submit(node: TaskId[?])(using strategy: CompletionService): Unit = { def submit(node: TaskId[?])(using strategy: CompletionService): Unit = {
val v = viewCache(node) val v = viewCache(node)
val rs = v.alist.transform(v.in)(getResult) val rs = v.computeInputs(getResult)
// v.alist.transform(v.in)(getResult)
strategy.submit(node, () => work(node, v.work(rs))) 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(node: TaskId[?]): Iterable[TaskId[?]] = dependencies(viewCache(node))
def dependencies(v: Node[?]): Iterable[TaskId[?]] = 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 runBefore(node: TaskId[?]): Seq[TaskId[?]] = triggers.runBefore.getOrElse(node, nilSeq)
def triggeredBy(node: TaskId[?]): Seq[TaskId[?]] = triggers.injectFor.getOrElse(node, nilSeq) def triggeredBy(node: TaskId[?]): Seq[TaskId[?]] = triggers.injectFor.getOrElse(node, nilSeq)

View File

@ -7,21 +7,16 @@
package sbt package sbt
import sbt.internal.util.AList
/** /**
* Represents a task node in a format understood by the task evaluation engine Execute. * Represents a task node in a format understood by the task evaluation engine Execute.
*
* @tparam Effect
* the task type constructor
* @tparam A * @tparam A
* the type computed by this node * the type computed by this node
*/ */
private[sbt] trait Node[A]: private[sbt] trait Node[A]:
type K[L[x]] type Inputs
def in: K[TaskId] def dependencies: List[TaskId[?]]
def alist: AList[K] def computeInputs(f: [a] => TaskId[a] => Result[a]): Inputs
/** Computes the result of this task given the results from the 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 end Node

View File

@ -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

View File

@ -10,7 +10,6 @@ package sbt.internal.util
import java.lang.Runnable import java.lang.Runnable
import java.util.concurrent.{ atomic, Executor, LinkedBlockingQueue } import java.util.concurrent.{ atomic, Executor, LinkedBlockingQueue }
import atomic.{ AtomicBoolean, AtomicInteger } import atomic.{ AtomicBoolean, AtomicInteger }
import Types.Id
enum EvaluationState: enum EvaluationState:
case New case New
@ -38,26 +37,19 @@ abstract class EvaluateSettings[ScopeType]:
private[this] val transform: [A] => Initialize[A] => INode[A] = [A] => private[this] val transform: [A] => Initialize[A] => INode[A] = [A] =>
(fa: Initialize[A]) => (fa: Initialize[A]) =>
fa match fa match
case k: Keyed[s, A] @unchecked => single(getStatic(k.scopedKey), k.transform) case k: Keyed[s, A] => single(getStatic(k.scopedKey), k.transform)
case a: Apply[k, A] @unchecked => case u: Uniform[s, A] => UniformNode(u.inputs.map(transform[s]), u.f)
MixedNode[k, A]( case a: Apply[k, A] =>
a.alist.transform[Initialize, INode](a.inputs) { transform }, MixedNode[k, A](TupleMapExtension.transform(a.inputs) { transform }, a.f)
a.f, case b: Bind[s, A] => BindNode[s, A](transform(b.in), x => transform(b.f(x)))
a.alist case v: Value[A] => constant(v.value)
) case v: ValidationCapture[a] => strictConstant(v.key: A)
case b: Bind[s, A] @unchecked => case t: TransformCapture => strictConstant(t.f: A)
new BindNode[s, A](transform(b.in), x => transform(b.f(x))) case o: Optional[s, A] =>
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 =>
o.a match o.a match
case None => constant(() => o.f(None)) case None => constant(() => o.f(None))
case Some(i) => single[s, A](transform(i), x => o.f(Some(x))) case Some(i) => single[s, A](transform(i), x => o.f(Some(x)))
case x if x == StaticScopes => case StaticScopes => strictConstant(allScopes)
// can't convince scalac that StaticScopes => T == Set[Scope]
strictConstant(allScopes.asInstanceOf[A])
// allScopes.asInstanceOf[A]
private[this] lazy val roots: Seq[INode[_]] = compiledSettings.flatMap { cs => private[this] lazy val roots: Seq[INode[_]] = compiledSettings.flatMap { cs =>
(cs.settings map { s => (cs.settings map { s =>
@ -88,7 +80,7 @@ abstract class EvaluateSettings[ScopeType]:
else ss.set(key.scope, key.key, node.get) 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()) 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 strictConstant[A1](v: A1): INode[A1] = constant(() => v)
private[this] def constant[A1](f: () => A1): INode[A1] = 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] = 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]: private[this] final class BindNode[A1, A2](in: INode[A1], f: A1 => INode[A2]) extends INode[A2]:
protected def dependsOn: Seq[INode[_]] = in :: Nil protected def dependsOn: Seq[INode[_]] = in :: Nil
@ -224,10 +216,15 @@ abstract class EvaluateSettings[ScopeType]:
} }
end BindNode 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]: extends INode[A1]:
protected override def dependsOn: Seq[INode[_]] = alist.toList(in) import TupleMapExtension.*
protected override def evaluate0(): Unit = setValue(f(alist.transform(in) { getValue })) protected override def dependsOn: Seq[INode[_]] = in.iterator.toList
end MixedNode 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 end EvaluateSettings

View File

@ -10,6 +10,7 @@ package sbt.internal.util
import Types.* import Types.*
import sbt.util.Show import sbt.util.Show
import Util.{ nil, nilSeq } import Util.{ nil, nilSeq }
import scala.jdk.CollectionConverters.*
sealed trait Settings[ScopeType]: sealed trait Settings[ScopeType]:
def data: Map[ScopeType, AttributeMap] 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 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] = 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 def app[Tup <: Tuple, A2](inputs: Tuple.Map[Tup, Initialize])(f: Tup => A2): Initialize[A2] =
alist: AList[K] Apply[Tup, A2](f, inputs)
): Initialize[A2] = Apply[K, A2](f, inputs, alist)
def ap[A1, A2](ff: Initialize[A1 => A2])(in: Initialize[A1]): Initialize[A2] = 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) => app[(A1 => A2, A1), A2]((ff, in)) { (f, a1) => f(a1) }
f(a1)
}(AList.tuple2[A1 => A2, A1])
def uniform[A1, A2](inputs: Seq[Initialize[A1]])(f: Seq[A1] => A2): Initialize[A2] = 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`. * 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] = def empty(implicit delegates: ScopeType => Seq[ScopeType]): Settings[ScopeType] =
Settings0(Map.empty, delegates) Settings0(Map.empty, delegates)
def asTransform(s: Settings[ScopeType]): [A] => ScopedKey[A] => Id[A] = [A] => def asTransform(s: Settings[ScopeType]): [A] => ScopedKey[A] => A =
(sk: ScopedKey[A]) => getValue(s, sk) [A] => (sk: ScopedKey[A]) => getValue(s, sk)
def getValue[T](s: Settings[ScopeType], k: ScopedKey[T]) = def getValue[T](s: Settings[ScopeType], k: ScopedKey[T]) =
s.get(k.scope, k.key) getOrElse (throw new InvalidReference(k)) s.get(k.scope, k.key) getOrElse (throw new InvalidReference(k))
@ -187,7 +185,6 @@ trait Init[ScopeType]:
case r => others.add(r) case r => others.add(r)
} }
result.addAll(others) result.addAll(others)
import scala.collection.JavaConverters._
result.asScala.toVector result.asScala.toVector
} }
@ -285,7 +282,6 @@ trait Init[ScopeType]:
delegateForKey(sMap, k, delegates(k.scope), ref, selfRefOk || !isFirst) delegateForKey(sMap, k, delegates(k.scope), ref, selfRefOk || !isFirst)
} }
import scala.collection.JavaConverters._
val undefined = new java.util.ArrayList[Undefined] val undefined = new java.util.ArrayList[Undefined]
val result = new java.util.concurrent.ConcurrentHashMap[ScopedKey[_], Any] val result = new java.util.concurrent.ConcurrentHashMap[ScopedKey[_], Any]
val backing = sMap.toSeq val backing = sMap.toSeq
@ -437,9 +433,7 @@ trait Init[ScopeType]:
): Flattened = ): Flattened =
new Flattened( new Flattened(
key, key,
deps.flatMap(dep => deps.flatMap(dep => if (dep.key.isLocal) cmap(dep).dependencies else Seq[ScopedKey[_]](dep))
if (dep.key.isLocal) cmap(dep).dependencies else Seq[ScopedKey[_]](dep).toIterable
)
) )
val empty = Map.empty[ScopedKey[_], Flattened] val empty = Map.empty[ScopedKey[_], Flattened]
@ -660,13 +654,13 @@ trait Init[ScopeType]:
private[sbt] def validateKeyReferenced(g: ValidateKeyRef): ValidatedInit[A1] private[sbt] def validateKeyReferenced(g: ValidateKeyRef): ValidatedInit[A1]
def evaluate(map: Settings[ScopeType]): 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] = def zipWith[A2, U](o: Initialize[A2])(f: (A1, A2) => U): Initialize[U] =
zipTupled(o)(f.tupled) zipTupled(o)(f.tupled)
private[this] def zipTupled[A2, U](o: Initialize[A2])(f: ((A1, A2)) => U): Initialize[U] = 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. */ /** A fold on the static attributes of this and nested Initializes. */
private[sbt] def processAttributes[S](init: S)(f: (S, AttributeMap) => S): S 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]]): final class JoinInitSeq[A1](s: Seq[Initialize[A1]]):
def joinWith[A2](f: Seq[A1] => A2): Initialize[A2] = uniform(s)(f) 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 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] => 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]]]]) (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)) (fa: Initialize[A]) => (fa.mapReferenced(g))
private[this] def mapConstantK(g: MapConstant): [A] => Initialize[A] => Initialize[A] = [A] => private[this] def mapConstantK(g: MapConstant): [A] => Initialize[A] => Initialize[A] = [A] =>
(fa: Initialize[A]) => (fa.mapConstant(g)) (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)) (fa: Initialize[A]) => (fa.evaluate(g))
private[this] def deps(ls: Seq[Initialize[_]]): Seq[ScopedKey[_]] = ls.flatMap(_.dependencies) 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`. * @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]: trait KeyedInitialize[A1] extends Keyed[A1, A1]:
final val transform = idFun[A1] final val transform = identity[A1]
end KeyedInitialize end KeyedInitialize
private[sbt] final class TransformCapture(val f: [x] => Initialize[x] => Initialize[x]) private[sbt] final class TransformCapture(val f: [x] => Initialize[x] => Initialize[x])
@ -957,34 +951,60 @@ trait Init[ScopeType]:
init init
end StaticScopes end StaticScopes
private[sbt] final class Apply[K[F[x]], A1]( private[sbt] final class Uniform[A1, A2](val f: Seq[A1] => A2, val inputs: List[Initialize[A1]])
val f: K[Id] => A1, extends Initialize[A2]:
val inputs: K[Initialize], override def dependencies: Seq[ScopedKey[_]] = deps(inputs)
val alist: AList[K] override def mapReferenced(g: MapScoped): Initialize[A2] =
) extends Initialize[A1]: Uniform(f, inputs.map(_.mapReferenced(g)))
override def dependencies: Seq[ScopedKey[_]] = deps(alist.toList(inputs)) override def mapConstant(g: MapConstant): Initialize[A2] =
override def mapReferenced(g: MapScoped): Initialize[A1] = mapInputs(mapReferencedK(g)) Uniform(f, inputs.map(_.mapConstant(g)))
override def mapConstant(g: MapConstant): Initialize[A1] = mapInputs(mapConstantK(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 apply[A2](g: A1 => A2): Initialize[A2] = Apply(g compose f, inputs, alist) override def validateKeyReferenced(g: ValidateKeyRef): ValidatedInit[A2] =
val tx = inputs.map(_.validateKeyReferenced(g))
def mapInputs(g: [a] => Initialize[a] => Initialize[a]): Initialize[A1] = val undefs = tx.flatMap(_.left.toSeq.flatten)
Apply(f, alist.transform(inputs) { g }, alist) if undefs.isEmpty then Right(Uniform(f, tx.map(_.right.get)))
override def evaluate(ss: Settings[ScopeType]): A1 =
f(alist.transform(inputs) { 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 get = [A] => (fa: ValidatedInit[A]) => (fa.right.get)
if undefs.isEmpty then Right(Apply(f, alist.transform(tx) { get }, alist))
else Left(undefs) else Left(undefs)
private[sbt] override def processAttributes[A2](init: A2)(f: (A2, AttributeMap) => A2): A2 = private[sbt] override def processAttributes[A2](init: A2)(f: (A2, AttributeMap) => A2): A2 =
alist.toList(inputs).foldLeft(init) { (v, i) => inputs.foldLeft(init)((v, i) => i.processAttributes(v)(f))
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]:
import sbt.internal.util.TupleMapExtension.*
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)))
override def apply[A2](g: A1 => A2): Initialize[A2] = Apply(g compose f, inputs)
override def evaluate(ss: Settings[ScopeType]): A1 = f(inputs.unmap(evaluateK(ss)))
override def validateKeyReferenced(g: ValidateKeyRef): ValidatedInit[A1] =
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, tx.transform(get)))
else Left(undefs.toSeq)
private[sbt] override def processAttributes[A2](init: A2)(f: (A2, AttributeMap) => A2): A2 =
inputs.iterator.toList.foldLeft(init) { (v, i) => i.processAttributes(v)(f) }
end Apply end Apply
private def remove[A](s: Seq[A], v: A) = s.filterNot(_ == v) private def remove[A](s: Seq[A], v: A) = s.filterNot(_ == v)

View File

@ -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

View File

@ -20,11 +20,6 @@ trait TypeFunctions:
type Compose[F1[_], F2[_]] = [a] =>> F1[F2[a]] 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]] } sealed trait [A[_], B[_]] { type l[T] = A[B[T]] }
private type AnyLeft[A] = Left[A, Nothing] private type AnyLeft[A] = Left[A, Nothing]
private type AnyRight[A] = Right[Nothing, A] private type AnyRight[A] = Right[Nothing, A]

View File

@ -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

View File

@ -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"))
}