Merge pull request #7456 from adpi2/refactor-alist

[sbt 2.x] Remove `AList`, replace it with `TupleMapExtension`
This commit is contained in:
adpi2 2023-12-13 16:57:51 +01:00 committed by GitHub
commit dd0d43bab4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 278 additions and 518 deletions

View File

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

View File

@ -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] 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] val inputs: Tuple.Map[Tup, App] =
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 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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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]))
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: 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]))
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)

View File

@ -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])
def toNode[A1, K1[F[_]]: AList](
inputs: K1[TaskId]
)(f: K1[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 = 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, 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

View File

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

View File

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

View File

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

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

View File

@ -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]
) 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))
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 apply[A2](g: A1 => A2): Initialize[A2] = Apply(g compose f, inputs, alist)
def mapInputs(g: [a] => Initialize[a] => Initialize[a]): Initialize[A1] =
Apply(f, alist.transform(inputs) { g }, alist)
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))
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 =
alist.toList(inputs).foldLeft(init) { (v, i) =>
i.processAttributes(v)(f)
}
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]:
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
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]]
/**
* 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]

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