mirror of https://github.com/sbt/sbt.git
Merge pull request #3650 from dwijnand/kind-projector
Add and use kind-projector
This commit is contained in:
commit
7e1a904b95
34
build.sbt
34
build.sbt
|
|
@ -51,6 +51,7 @@ def commonSettings: Seq[Setting[_]] =
|
|||
resolvers += Resolver.typesafeIvyRepo("releases"),
|
||||
resolvers += Resolver.sonatypeRepo("snapshots"),
|
||||
resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/",
|
||||
addCompilerPlugin("org.spire-math" % "kind-projector" % "0.9.4" cross CrossVersion.binary),
|
||||
concurrentRestrictions in Global += Util.testExclusiveRestriction,
|
||||
testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"),
|
||||
testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "2"),
|
||||
|
|
@ -143,6 +144,18 @@ val collectionProj = (project in file("internal") / "util-collection")
|
|||
mimaBinaryIssueFilters ++= Seq(
|
||||
// Added private[sbt] method to capture State attributes.
|
||||
exclude[ReversedMissingMethodProblem]("sbt.internal.util.AttributeMap.setCond"),
|
||||
|
||||
// Dropped in favour of kind-projector's inline type lambda syntax
|
||||
exclude[MissingClassProblem]("sbt.internal.util.TypeFunctions$P1of2"),
|
||||
|
||||
// Dropped in favour of kind-projector's polymorphic lambda literals
|
||||
exclude[MissingClassProblem]("sbt.internal.util.Param"),
|
||||
exclude[MissingClassProblem]("sbt.internal.util.Param$"),
|
||||
|
||||
// Dropped in favour of plain scala.Function, and its compose method
|
||||
exclude[MissingClassProblem]("sbt.internal.util.Fn1"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.util.TypeFunctions.toFn1"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.internal.util.Types.toFn1"),
|
||||
),
|
||||
)
|
||||
.configure(addSbtUtilPosition)
|
||||
|
|
@ -418,7 +431,18 @@ lazy val sbtProj = (project in file("sbt"))
|
|||
crossScalaVersions := Seq(baseScalaVersion),
|
||||
crossPaths := false,
|
||||
mimaSettings,
|
||||
mimaBinaryIssueFilters ++= sbtIgnoredProblems,
|
||||
mimaBinaryIssueFilters ++= Vector(
|
||||
// Added more items to Import trait.
|
||||
exclude[ReversedMissingMethodProblem]("sbt.Import.sbt$Import$_setter_$WatchSource_="),
|
||||
exclude[ReversedMissingMethodProblem]("sbt.Import.WatchSource"),
|
||||
|
||||
// Dropped in favour of kind-projector's polymorphic lambda literals
|
||||
exclude[DirectMissingMethodProblem]("sbt.Import.Param"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.package.Param"),
|
||||
|
||||
// Dropped in favour of plain scala.Function, and its compose method
|
||||
exclude[DirectMissingMethodProblem]("sbt.package.toFn1"),
|
||||
)
|
||||
)
|
||||
.configure(addSbtCompilerBridge)
|
||||
|
||||
|
|
@ -461,14 +485,6 @@ lazy val vscodePlugin = (project in file("vscode-sbt-scala"))
|
|||
}
|
||||
)
|
||||
|
||||
lazy val sbtIgnoredProblems = {
|
||||
Seq(
|
||||
// Added more items to Import trait.
|
||||
exclude[ReversedMissingMethodProblem]("sbt.Import.sbt$Import$_setter_$WatchSource_="),
|
||||
exclude[ReversedMissingMethodProblem]("sbt.Import.WatchSource")
|
||||
)
|
||||
}
|
||||
|
||||
def scriptedTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
|
||||
val result = scriptedSource(dir => (s: State) => Scripted.scriptedParser(dir)).parsed
|
||||
// publishLocalBinAll.value // TODO: Restore scripted needing only binary jars.
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ import scala.reflect._
|
|||
import macros._
|
||||
|
||||
object Instance {
|
||||
type Aux[M0[_]] = Instance { type M[x] = M0[x] }
|
||||
type Aux2[M0[_], N[_]] = Instance { type M[x] = M0[N[x]] }
|
||||
|
||||
final val ApplyName = "app"
|
||||
final val FlattenName = "flatten"
|
||||
final val PureName = "pure"
|
||||
|
|
@ -204,19 +207,18 @@ object Instance {
|
|||
|
||||
import Types._
|
||||
|
||||
implicit def applicativeInstance[A[_]](
|
||||
implicit ap: Applicative[A]): Instance { type M[x] = A[x] } = new Instance {
|
||||
type M[x] = A[x]
|
||||
def app[K[L[x]], Z](in: K[A], f: K[Id] => Z)(implicit a: AList[K]) = a.apply[A, Z](in, f)
|
||||
def map[S, T](in: A[S], f: S => T) = ap.map(f, in)
|
||||
def pure[S](s: () => S): M[S] = ap.pure(s())
|
||||
}
|
||||
implicit def applicativeInstance[A[_]](implicit ap: Applicative[A]): Instance.Aux[A] =
|
||||
new Instance {
|
||||
type M[x] = A[x]
|
||||
def app[K[L[x]], Z](in: K[A], f: K[Id] => Z)(implicit a: AList[K]) = a.apply[A, Z](in, f)
|
||||
def map[S, T](in: A[S], f: S => T) = ap.map(f, in)
|
||||
def pure[S](s: () => S): M[S] = ap.pure(s())
|
||||
}
|
||||
|
||||
type AI[A[_]] = Instance { type M[x] = A[x] }
|
||||
def compose[A[_], B[_]](implicit a: AI[A], b: AI[B]): Instance { type M[x] = A[B[x]] } =
|
||||
def compose[A[_], B[_]](implicit a: Aux[A], b: Aux[B]): Instance.Aux2[A, B] =
|
||||
new Composed[A, B](a, b)
|
||||
// made a public, named, unsealed class because of trouble with macros and inference when the Instance is not an object
|
||||
class Composed[A[_], B[_]](a: AI[A], b: AI[B]) extends Instance {
|
||||
class Composed[A[_], B[_]](a: Aux[A], b: Aux[B]) extends Instance {
|
||||
type M[x] = A[B[x]]
|
||||
def pure[S](s: () => S): A[B[S]] = a.pure(() => b.pure(s))
|
||||
def map[S, T](in: M[S], f: S => T): M[T] = a.map(in, (bv: B[S]) => b.map(bv, f))
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ trait AList[K[L[x]]] {
|
|||
}
|
||||
|
||||
object AList {
|
||||
type Empty = AList[({ type l[L[x]] = Unit })#l]
|
||||
type Empty = AList[ConstK[Unit]#l]
|
||||
|
||||
/** AList for Unit, which represents a sequence that is always empty.*/
|
||||
val empty: Empty = new Empty {
|
||||
|
|
@ -37,7 +37,7 @@ object AList {
|
|||
def traverse[M[_], N[_], P[_]](in: Unit, f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[Unit] = np.pure(())
|
||||
}
|
||||
|
||||
type SeqList[T] = AList[({ type l[L[x]] = List[L[T]] })#l]
|
||||
type SeqList[T] = AList[λ[L[x] => List[L[T]]]]
|
||||
|
||||
/** AList for a homogeneous sequence. */
|
||||
def seq[T]: SeqList[T] = new SeqList[T] {
|
||||
|
|
@ -59,7 +59,7 @@ object AList {
|
|||
}
|
||||
|
||||
/** AList for the arbitrary arity data structure KList. */
|
||||
def klist[KL[M[_]] <: KList[M] { type Transform[N[_]] = KL[N] }]: AList[KL] = new AList[KL] {
|
||||
def klist[KL[M[_]] <: KList.Aux[M, KL]]: AList[KL] = new AList[KL] {
|
||||
def transform[M[_], N[_]](k: KL[M], f: M ~> N) = k.transform(f)
|
||||
def foldr[M[_], T](k: KL[M], f: (M[_], T) => T, init: T): T = k.foldr(f, init)
|
||||
override def apply[M[_], C](k: KL[M], f: KL[Id] => C)(implicit app: Applicative[M]): M[C] = k.apply(f)(app)
|
||||
|
|
@ -67,7 +67,7 @@ object AList {
|
|||
override def toList[M[_]](k: KL[M]) = k.toList
|
||||
}
|
||||
|
||||
type Single[A] = AList[({ type l[L[x]] = L[A] })#l]
|
||||
type Single[A] = AList[λ[L[x] => L[A]]]
|
||||
|
||||
/** AList for a single value. */
|
||||
def single[A]: Single[A] = new Single[A] {
|
||||
|
|
@ -76,7 +76,7 @@ object AList {
|
|||
def traverse[M[_], N[_], P[_]](a: M[A], f: M ~> (N ∙ P)#l)(implicit np: Applicative[N]): N[P[A]] = f(a)
|
||||
}
|
||||
|
||||
type ASplit[K[L[x]], B[x]] = AList[({ type l[L[x]] = K[(L ∙ B)#l] })#l]
|
||||
type ASplit[K[L[x]], B[x]] = AList[λ[L[x] => K[(L ∙ B)#l]]]
|
||||
|
||||
/** AList that operates on the outer type constructor `A` of a composition `[x] A[B[x]]` for type constructors `A` and `B`*/
|
||||
def asplit[K[L[x]], B[x]](base: AList[K]): ASplit[K, B] = new ASplit[K, B] {
|
||||
|
|
|
|||
|
|
@ -196,11 +196,9 @@ object AttributeMap {
|
|||
def apply(entries: AttributeEntry[_]*): AttributeMap = empty ++ entries
|
||||
|
||||
/** Presents an `AttributeMap` as a natural transformation. */
|
||||
implicit def toNatTrans(map: AttributeMap): AttributeKey ~> Id = new (AttributeKey ~> Id) {
|
||||
def apply[T](key: AttributeKey[T]): T = map(key)
|
||||
}
|
||||
|
||||
implicit def toNatTrans(map: AttributeMap): AttributeKey ~> Id = λ[AttributeKey ~> Id](map(_))
|
||||
}
|
||||
|
||||
private class BasicAttributeMap(private val backing: Map[AttributeKey[_], Any])
|
||||
extends AttributeMap {
|
||||
|
||||
|
|
|
|||
|
|
@ -32,27 +32,25 @@ abstract class EvaluateSettings[Scope] {
|
|||
private[this] def getStatic[T](key: ScopedKey[T]): INode[T] =
|
||||
static get key getOrElse sys.error("Illegal reference to key " + key)
|
||||
|
||||
private[this] val transform: Initialize ~> INode = new (Initialize ~> INode) {
|
||||
def apply[T](i: Initialize[T]): INode[T] = i match {
|
||||
case k: Keyed[s, T] @unchecked => single(getStatic(k.scopedKey), k.transform)
|
||||
case a: Apply[k, T] @unchecked =>
|
||||
new MixedNode[k, T](
|
||||
a.alist.transform[Initialize, INode](a.inputs, transform),
|
||||
a.f,
|
||||
a.alist
|
||||
)
|
||||
case b: Bind[s, T] @unchecked => new BindNode[s, T](transform(b.in), x => transform(b.f(x)))
|
||||
case v: Value[T] @unchecked => constant(v.value)
|
||||
case v: ValidationCapture[T] @unchecked => strictConstant(v.key)
|
||||
case t: TransformCapture => strictConstant(t.f)
|
||||
case o: Optional[s, T] @unchecked =>
|
||||
o.a match {
|
||||
case None => constant(() => o.f(None))
|
||||
case Some(i) => single[s, T](transform(i), x => o.f(Some(x)))
|
||||
}
|
||||
case x if x == StaticScopes =>
|
||||
strictConstant(allScopes.asInstanceOf[T]) // can't convince scalac that StaticScopes => T == Set[Scope]
|
||||
}
|
||||
private[this] val transform: Initialize ~> INode = λ[Initialize ~> INode] {
|
||||
case k: Keyed[s, A1$] @unchecked => single(getStatic(k.scopedKey), k.transform)
|
||||
case a: Apply[k, A1$] @unchecked =>
|
||||
new MixedNode[k, A1$](
|
||||
a.alist.transform[Initialize, INode](a.inputs, transform),
|
||||
a.f,
|
||||
a.alist
|
||||
)
|
||||
case b: Bind[s, A1$] @unchecked => new BindNode[s, A1$](transform(b.in), x => transform(b.f(x)))
|
||||
case v: Value[A1$] @unchecked => constant(v.value)
|
||||
case v: ValidationCapture[A1$] @unchecked => strictConstant(v.key)
|
||||
case t: TransformCapture => strictConstant(t.f)
|
||||
case o: Optional[s, A1$] @unchecked =>
|
||||
o.a match {
|
||||
case None => constant(() => o.f(None))
|
||||
case Some(i) => single[s, A1$](transform(i), x => o.f(Some(x)))
|
||||
}
|
||||
case x if x == StaticScopes =>
|
||||
strictConstant(allScopes.asInstanceOf[A1$]) // can't convince scalac that StaticScopes => T == Set[Scope]
|
||||
}
|
||||
|
||||
private[this] lazy val roots: Seq[INode[_]] = compiledSettings flatMap { cs =>
|
||||
|
|
@ -84,7 +82,7 @@ abstract class EvaluateSettings[Scope] {
|
|||
if (key.key.isLocal) ss else ss.set(key.scope, key.key, node.get)
|
||||
}
|
||||
|
||||
private[this] val getValue = new (INode ~> Id) { def apply[T](node: INode[T]) = node.get }
|
||||
private[this] val getValue = λ[INode ~> Id](_.get)
|
||||
|
||||
private[this] def submitEvaluate(node: INode[_]) = submit(node.evaluate())
|
||||
|
||||
|
|
@ -204,7 +202,7 @@ abstract class EvaluateSettings[Scope] {
|
|||
new MixedNode[ConstK[Unit]#l, T]((), _ => f(), AList.empty)
|
||||
|
||||
private[this] def single[S, T](in: INode[S], f: S => T): INode[T] =
|
||||
new MixedNode[({ type l[L[x]] = L[S] })#l, T](in, f, AList.single[S])
|
||||
new MixedNode[λ[L[x] => L[S]], T](in, f, AList.single[S])
|
||||
|
||||
private[this] final class BindNode[S, T](in: INode[S], f: S => INode[T]) extends INode[T] {
|
||||
protected def dependsOn = in :: Nil
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ sealed trait KList[+M[_]] {
|
|||
/** Discards the heterogeneous type information and constructs a plain List from this KList's elements. */
|
||||
def toList: List[M[_]]
|
||||
}
|
||||
object KList {
|
||||
type Aux[+M[_], Transform0[N[_]]] = KList[M] { type Transform[N[_]] = Transform0[N] }
|
||||
}
|
||||
|
||||
final case class KCons[H, +T <: KList[M], +M[_]](head: M[H], tail: T) extends KList[M] {
|
||||
final type Transform[N[_]] = KCons[H, tail.Transform[N], N]
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ trait IMap[K[_], V[_]] extends (K ~> V) with RMap[K, V] {
|
|||
def remove[T](k: K[T]): IMap[K, V]
|
||||
def mapValue[T](k: K[T], init: V[T], f: V[T] => V[T]): IMap[K, V]
|
||||
def mapValues[V2[_]](f: V ~> V2): IMap[K, V2]
|
||||
def mapSeparate[VL[_], VR[_]](f: V ~> ({ type l[T] = Either[VL[T], VR[T]] })#l)
|
||||
: (IMap[K, VL], IMap[K, VR])
|
||||
def mapSeparate[VL[_], VR[_]](f: V ~> λ[T => Either[VL[T], VR[T]]]): (IMap[K, VL], IMap[K, VR])
|
||||
}
|
||||
|
||||
trait PMap[K[_], V[_]] extends (K ~> V) with RMap[K, V] {
|
||||
|
|
@ -69,7 +68,7 @@ object IMap {
|
|||
def mapValues[V2[_]](f: V ~> V2) =
|
||||
new IMap0[K, V2](backing.mapValues(x => f(x)))
|
||||
|
||||
def mapSeparate[VL[_], VR[_]](f: V ~> ({ type l[T] = Either[VL[T], VR[T]] })#l) = {
|
||||
def mapSeparate[VL[_], VR[_]](f: V ~> λ[T => Either[VL[T], VR[T]]]) = {
|
||||
val mapped = backing.iterator.map {
|
||||
case (k, v) =>
|
||||
f(v) match {
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2011 - 2017, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under BSD-3-Clause license (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt.internal.util
|
||||
|
||||
// Used to emulate ~> literals
|
||||
trait Param[A[_], B[_]] {
|
||||
type T
|
||||
def in: A[T]
|
||||
def ret(out: B[T]): Unit
|
||||
def ret: B[T]
|
||||
}
|
||||
|
||||
object Param {
|
||||
implicit def pToT[A[_], B[_]](p: Param[A, B] => Unit): A ~> B = new (A ~> B) {
|
||||
def apply[s](a: A[s]): B[s] = {
|
||||
val v: Param[A, B] { type T = s } = new Param[A, B] {
|
||||
type T = s
|
||||
def in = a
|
||||
private var r: B[T] = _
|
||||
def ret(b: B[T]): Unit = { r = b }
|
||||
def ret: B[T] = r
|
||||
}
|
||||
p(v)
|
||||
v.ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -101,14 +101,14 @@ trait Init[Scope] {
|
|||
def bind[S, T](in: Initialize[S])(f: S => Initialize[T]): Initialize[T] = new Bind(f, in)
|
||||
|
||||
def map[S, T](in: Initialize[S])(f: S => T): Initialize[T] =
|
||||
new Apply[({ type l[L[x]] = L[S] })#l, T](f, in, AList.single[S])
|
||||
new Apply[λ[L[x] => L[S]], T](f, in, AList.single[S])
|
||||
|
||||
def app[K[L[x]], T](inputs: K[Initialize])(f: K[Id] => T)(
|
||||
implicit alist: AList[K]
|
||||
): Initialize[T] = new Apply[K, T](f, inputs, alist)
|
||||
|
||||
def uniform[S, T](inputs: Seq[Initialize[S]])(f: Seq[S] => T): Initialize[T] =
|
||||
new Apply[({ type l[L[x]] = List[L[S]] })#l, T](f, inputs.toList, AList.seq[S])
|
||||
new Apply[λ[L[x] => List[L[S]]], T](f, inputs.toList, AList.seq[S])
|
||||
|
||||
/**
|
||||
* The result of this initialization is the validated `key`.
|
||||
|
|
@ -156,9 +156,7 @@ trait Init[Scope] {
|
|||
def empty(implicit delegates: Scope => Seq[Scope]): Settings[Scope] =
|
||||
new Settings0(Map.empty, delegates)
|
||||
|
||||
def asTransform(s: Settings[Scope]): ScopedKey ~> Id = new (ScopedKey ~> Id) {
|
||||
def apply[T](k: ScopedKey[T]): T = getValue(s, k)
|
||||
}
|
||||
def asTransform(s: Settings[Scope]): ScopedKey ~> Id = λ[ScopedKey ~> Id](k => getValue(s, k))
|
||||
|
||||
def getValue[T](s: Settings[Scope], k: ScopedKey[T]) =
|
||||
s.get(k.scope, k.key) getOrElse (throw new InvalidReference(k))
|
||||
|
|
@ -246,13 +244,11 @@ trait Init[Scope] {
|
|||
|
||||
type ValidatedSettings[T] = Either[Seq[Undefined], SettingSeq[T]]
|
||||
|
||||
val f = new (SettingSeq ~> ValidatedSettings) {
|
||||
def apply[T](ks: Seq[Setting[T]]) = {
|
||||
val (undefs, valid) = Util.separate(ks.zipWithIndex) {
|
||||
case (s, i) => s validateKeyReferenced refMap(s, i == 0)
|
||||
}
|
||||
if (undefs.isEmpty) Right(valid) else Left(undefs.flatten)
|
||||
val f = λ[SettingSeq ~> ValidatedSettings] { (ks: Seq[Setting[_]]) =>
|
||||
val (undefs, valid) = Util.separate(ks.zipWithIndex) {
|
||||
case (s, i) => s validateKeyReferenced refMap(s, i == 0)
|
||||
}
|
||||
if (undefs.isEmpty) Right(valid) else Left(undefs.flatten)
|
||||
}
|
||||
|
||||
type Undefs[_] = Seq[Undefined]
|
||||
|
|
@ -560,7 +556,7 @@ trait Init[Scope] {
|
|||
def zip[S](o: Initialize[S]): Initialize[(T, S)] = zipTupled(o)(idFun)
|
||||
def zipWith[S, U](o: Initialize[S])(f: (T, S) => U): Initialize[U] = zipTupled(o)(f.tupled)
|
||||
private[this] def zipTupled[S, U](o: Initialize[S])(f: ((T, S)) => U): Initialize[U] =
|
||||
new Apply[({ type l[L[x]] = (L[T], L[S]) })#l, U](f, (this, o), AList.tuple2[T, S])
|
||||
new Apply[λ[L[x] => (L[T], L[S])], U](f, (this, o), AList.tuple2[T, S])
|
||||
|
||||
/** A fold on the static attributes of this and nested Initializes. */
|
||||
private[sbt] def processAttributes[S](init: S)(f: (S, AttributeMap) => S): S
|
||||
|
|
@ -577,8 +573,7 @@ trait Init[Scope] {
|
|||
def join[T](inits: Seq[Initialize[T]]): Initialize[Seq[T]] = uniform(inits)(idFun)
|
||||
|
||||
def joinAny[M[_]](inits: Seq[Initialize[M[T]] forSome { type T }]): Initialize[Seq[M[_]]] =
|
||||
join(inits.asInstanceOf[Seq[Initialize[M[Any]]]])
|
||||
.asInstanceOf[Initialize[Seq[M[T] forSome { type T }]]]
|
||||
join(inits.asInstanceOf[Seq[Initialize[M[_]]]])
|
||||
}
|
||||
|
||||
object SettingsDefinition {
|
||||
|
|
@ -686,23 +681,15 @@ trait Init[Scope] {
|
|||
case Right(x) => x
|
||||
}
|
||||
|
||||
private[this] lazy val getValidated =
|
||||
new (ValidatedInit ~> Initialize) { def apply[T](v: ValidatedInit[T]) = handleUndefined[T](v) }
|
||||
private[this] lazy val getValidated = λ[ValidatedInit ~> Initialize](handleUndefined(_))
|
||||
|
||||
// mainly for reducing generated class count
|
||||
private[this] def validateKeyReferencedT(g: ValidateKeyRef) =
|
||||
new (Initialize ~> ValidatedInit) {
|
||||
def apply[T](i: Initialize[T]) = i validateKeyReferenced g
|
||||
}
|
||||
λ[Initialize ~> ValidatedInit](_ validateKeyReferenced g)
|
||||
|
||||
private[this] def mapReferencedT(g: MapScoped) =
|
||||
new (Initialize ~> Initialize) { def apply[T](i: Initialize[T]) = i mapReferenced g }
|
||||
|
||||
private[this] def mapConstantT(g: MapConstant) =
|
||||
new (Initialize ~> Initialize) { def apply[T](i: Initialize[T]) = i mapConstant g }
|
||||
|
||||
private[this] def evaluateT(g: Settings[Scope]) =
|
||||
new (Initialize ~> Id) { def apply[T](i: Initialize[T]) = i evaluate g }
|
||||
private[this] def mapReferencedT(g: MapScoped) = λ[Initialize ~> Initialize](_ mapReferenced g)
|
||||
private[this] def mapConstantT(g: MapConstant) = λ[Initialize ~> Initialize](_ mapConstant g)
|
||||
private[this] def evaluateT(g: Settings[Scope]) = λ[Initialize ~> Id](_ evaluate g)
|
||||
|
||||
private[this] def deps(ls: Seq[Initialize[_]]): Seq[ScopedKey[_]] = ls.flatMap(_.dependencies)
|
||||
|
||||
|
|
@ -854,9 +841,7 @@ trait Init[Scope] {
|
|||
def validateKeyReferenced(g: ValidateKeyRef) = {
|
||||
val tx = alist.transform(inputs, validateKeyReferencedT(g))
|
||||
val undefs = alist.toList(tx).flatMap(_.left.toSeq.flatten)
|
||||
val get = new (ValidatedInit ~> Initialize) {
|
||||
def apply[B](vr: ValidatedInit[B]) = vr.right.get
|
||||
}
|
||||
val get = λ[ValidatedInit ~> Initialize](_.right.get)
|
||||
if (undefs.isEmpty) Right(new Apply(f, alist.transform(tx, get), alist)) else Left(undefs)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,25 +13,18 @@ trait TypeFunctions {
|
|||
sealed trait ConstK[A] { type l[L[x]] = A }
|
||||
sealed trait Compose[A[_], B[_]] { type Apply[T] = A[B[T]] }
|
||||
sealed trait ∙[A[_], B[_]] { type l[T] = A[B[T]] }
|
||||
sealed trait P1of2[M[_, _], A] { type Apply[B] = M[A, B]; type Flip[B] = M[B, A] }
|
||||
|
||||
final val left = new (Id ~> P1of2[Left, Nothing]#Flip) { def apply[T](t: T) = Left(t) }
|
||||
final val right = new (Id ~> P1of2[Right, Nothing]#Apply) { def apply[T](t: T) = Right(t) }
|
||||
final val some = new (Id ~> Some) { def apply[T](t: T) = Some(t) }
|
||||
final val left = λ[Id ~> Left[?, Nothing]](Left(_))
|
||||
final val right = λ[Id ~> Right[Nothing, ?]](Right(_))
|
||||
final val some = λ[Id ~> Some](Some(_))
|
||||
final def idFun[T] = (t: T) => t
|
||||
final def const[A, B](b: B): A => B = _ => b
|
||||
final def idK[M[_]]: M ~> M = new (M ~> M) { def apply[T](m: M[T]): M[T] = m }
|
||||
final def idK[M[_]]: M ~> M = λ[M ~> M](m => m)
|
||||
|
||||
def nestCon[M[_], N[_], G[_]](f: M ~> N): (M ∙ G)#l ~> (N ∙ G)#l =
|
||||
f.asInstanceOf[(M ∙ G)#l ~> (N ∙ G)#l] // implemented with a cast to avoid extra object+method call. castless version:
|
||||
|
||||
/* new ( (M ∙ G)#l ~> (N ∙ G)#l ) {
|
||||
def apply[T](mg: M[G[T]]): N[G[T]] = f(mg)
|
||||
} */
|
||||
|
||||
implicit def toFn1[A, B](f: A => B): Fn1[A, B] = new Fn1[A, B] {
|
||||
def ∙[C](g: C => A) = f compose g
|
||||
}
|
||||
f.asInstanceOf[(M ∙ G)#l ~> (N ∙ G)#l] // implemented with a cast to avoid extra object+method call.
|
||||
// castless version:
|
||||
// λ[(M ∙ G)#l ~> (N ∙ G)#l](f(_))
|
||||
|
||||
type Endo[T] = T => T
|
||||
type ~>|[A[_], B[_]] = A ~> Compose[Option, B]#Apply
|
||||
|
|
@ -42,17 +35,13 @@ object TypeFunctions extends TypeFunctions
|
|||
trait ~>[-A[_], +B[_]] { outer =>
|
||||
def apply[T](a: A[T]): B[T]
|
||||
// directly on ~> because of type inference limitations
|
||||
final def ∙[C[_]](g: C ~> A): C ~> B = new (C ~> B) { def apply[T](c: C[T]) = outer.apply(g(c)) }
|
||||
final def ∙[C[_]](g: C ~> A): C ~> B = λ[C ~> B](c => outer.apply(g(c)))
|
||||
final def ∙[C, D](g: C => D)(implicit ev: D <:< A[D]): C => B[D] = i => apply(ev(g(i)))
|
||||
final def fn[T] = (t: A[T]) => apply[T](t)
|
||||
}
|
||||
|
||||
object ~> {
|
||||
import TypeFunctions._
|
||||
val Id: Id ~> Id = new (Id ~> Id) { def apply[T](a: T): T = a }
|
||||
val Id: Id ~> Id = idK[Id]
|
||||
implicit def tcIdEquals: (Id ~> Id) = Id
|
||||
}
|
||||
|
||||
trait Fn1[A, B] {
|
||||
def ∙[C](g: C => A): C => B
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2011 - 2017, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under BSD-3-Clause license (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt.internal.util
|
||||
|
||||
// compilation test
|
||||
object LiteralTest {
|
||||
def x[A[_], B[_]](f: A ~> B) = f
|
||||
|
||||
import Param._
|
||||
val f = x { (p: Param[Option, List]) =>
|
||||
p.ret(p.in.toList)
|
||||
}
|
||||
|
||||
val a: List[Int] = f(Some(3))
|
||||
val b: List[String] = f(Some("aa"))
|
||||
}
|
||||
|
|
@ -21,9 +21,7 @@ import scala.util.control.NonFatal
|
|||
*/
|
||||
private[sbt] final class Previous(streams: Streams, referenced: IMap[ScopedTaskKey, Referenced]) {
|
||||
private[this] val map = referenced.mapValues(toValue)
|
||||
private[this] def toValue = new (Referenced ~> ReferencedValue) {
|
||||
def apply[T](x: Referenced[T]) = new ReferencedValue(x)
|
||||
}
|
||||
private[this] def toValue = λ[Referenced ~> ReferencedValue](new ReferencedValue(_))
|
||||
|
||||
private[this] final class ReferencedValue[T](referenced: Referenced[T]) {
|
||||
import referenced.{ stamped, task }
|
||||
|
|
|
|||
|
|
@ -434,14 +434,10 @@ object Scoped {
|
|||
|
||||
protected def convert[M[_], Ret](f: Fun[M, Ret]): K[M] => Ret
|
||||
|
||||
private[this] val inputs: K[App] =
|
||||
a.transform(
|
||||
keys,
|
||||
new (ScopedTaskable ~> App) { def apply[T](in: ScopedTaskable[T]): App[T] = in.toTask }
|
||||
)
|
||||
private[this] val inputs: K[App] = a.transform(keys, λ[ScopedTaskable ~> App](_.toTask))
|
||||
|
||||
private[this] def onTasks[T](f: K[Task] => Task[T]): App[T] =
|
||||
Def.app[({ type l[L[x]] = K[(L ∙ Task)#l] })#l, Task[T]](inputs)(f)(AList.asplit[K, Task](a))
|
||||
Def.app[λ[L[x] => K[(L ∙ Task)#l]], Task[T]](inputs)(f)(AList.asplit[K, Task](a))
|
||||
|
||||
def flatMap[T](f: Fun[Id, Task[T]]): App[T] = onTasks(_.flatMap(convert(f)))
|
||||
def flatMapR[T](f: Fun[Result, Task[T]]): App[T] = onTasks(_.flatMapR(convert(f)))
|
||||
|
|
|
|||
|
|
@ -515,10 +515,7 @@ object Project extends ProjectExtra {
|
|||
def fillTaskAxis(scoped: ScopedKey[_]): ScopedKey[_] =
|
||||
ScopedKey(Scope.fillTaskAxis(scoped.scope, scoped.key), scoped.key)
|
||||
|
||||
def mapScope(f: Scope => Scope) = new (ScopedKey ~> ScopedKey) {
|
||||
def apply[T](key: ScopedKey[T]) =
|
||||
ScopedKey(f(key.scope), key.key)
|
||||
}
|
||||
def mapScope(f: Scope => Scope) = λ[ScopedKey ~> ScopedKey](k => ScopedKey(f(k.scope), k.key))
|
||||
|
||||
def transform(g: Scope => Scope, ss: Seq[Def.Setting[_]]): Seq[Def.Setting[_]] = {
|
||||
val f = mapScope(g)
|
||||
|
|
|
|||
|
|
@ -291,12 +291,12 @@ private[sbt] object Load {
|
|||
// 3. resolvedScoped is replaced with the defining key as a value
|
||||
// Note: this must be idempotent.
|
||||
def finalTransforms(ss: Seq[Setting[_]]): Seq[Setting[_]] = {
|
||||
def mapSpecial(to: ScopedKey[_]) = new (ScopedKey ~> ScopedKey) {
|
||||
def apply[T](key: ScopedKey[T]) =
|
||||
def mapSpecial(to: ScopedKey[_]) = λ[ScopedKey ~> ScopedKey](
|
||||
(key: ScopedKey[_]) =>
|
||||
if (key.key == streams.key)
|
||||
ScopedKey(Scope.fillTaskAxis(Scope.replaceThis(to.scope)(key.scope), to.key), key.key)
|
||||
else key
|
||||
}
|
||||
)
|
||||
def setDefining[T] =
|
||||
(key: ScopedKey[T], value: T) =>
|
||||
value match {
|
||||
|
|
@ -304,13 +304,13 @@ private[sbt] object Load {
|
|||
case ik: InputTask[t] => ik.mapTask(tk => setDefinitionKey(tk, key)).asInstanceOf[T]
|
||||
case _ => value
|
||||
}
|
||||
def setResolved(defining: ScopedKey[_]) = new (ScopedKey ~> Option) {
|
||||
def apply[T](key: ScopedKey[T]): Option[T] =
|
||||
def setResolved(defining: ScopedKey[_]) = λ[ScopedKey ~> Option](
|
||||
(key: ScopedKey[_]) =>
|
||||
key.key match {
|
||||
case resolvedScoped.key => Some(defining.asInstanceOf[T])
|
||||
case resolvedScoped.key => Some(defining.asInstanceOf[A1$])
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
ss.map(s =>
|
||||
s mapConstant setResolved(s.key) mapReferenced mapSpecial(s.key) mapInit setDefining)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,6 @@ trait Import {
|
|||
type FeedbackProvidedException = sbt.internal.util.FeedbackProvidedException
|
||||
type FilePosition = sbt.internal.util.FilePosition
|
||||
type FilterLogger = sbt.internal.util.FilterLogger
|
||||
type Fn1[A, B] = sbt.internal.util.Fn1[A, B]
|
||||
val FullLogger = sbt.internal.util.FullLogger
|
||||
type FullLogger = sbt.internal.util.FullLogger
|
||||
val FullReader = sbt.internal.util.FullReader
|
||||
|
|
@ -167,8 +166,6 @@ trait Import {
|
|||
val NoPosition = sbt.internal.util.NoPosition
|
||||
val PMap = sbt.internal.util.PMap
|
||||
type PMap[K[_], V[_]] = sbt.internal.util.PMap[K, V]
|
||||
val Param = sbt.internal.util.Param
|
||||
type Param[A[_], B[_]] = sbt.internal.util.Param[A, B]
|
||||
type RMap[K[_], V[_]] = sbt.internal.util.RMap[K, V]
|
||||
val RangePosition = sbt.internal.util.RangePosition
|
||||
type RangePosition = sbt.internal.util.RangePosition
|
||||
|
|
|
|||
|
|
@ -37,9 +37,7 @@ object Transform {
|
|||
|
||||
/** Applies `map`, returning the result if defined or returning the input unchanged otherwise.*/
|
||||
implicit def getOrId(map: Task ~>| Task): Task ~> Task =
|
||||
new (Task ~> Task) {
|
||||
def apply[T](in: Task[T]): Task[T] = map(in).getOrElse(in)
|
||||
}
|
||||
λ[Task ~> Task](in => map(in).getOrElse(in))
|
||||
|
||||
def apply(dummies: DummyTaskMap) = taskToNode(getOrId(dummyMap(dummies)))
|
||||
|
||||
|
|
@ -48,7 +46,7 @@ object Transform {
|
|||
case Pure(eval, _) => uniform(Nil)(_ => Right(eval()))
|
||||
case m: Mapped[t, k] => toNode[t, k](m.in)(right ∙ m.f)(m.alist)
|
||||
case m: FlatMapped[t, k] => toNode[t, k](m.in)(left ∙ m.f)(m.alist)
|
||||
case DependsOn(in, deps) => uniform(existToAny(deps))(const(Left(in)) ∙ all)
|
||||
case DependsOn(in, deps) => uniform(existToAny(deps))(const(Left(in)) compose all)
|
||||
case Join(in, f) => uniform(in)(f)
|
||||
}
|
||||
def inline[T](t: Task[T]) = t.work match {
|
||||
|
|
@ -58,7 +56,7 @@ object Transform {
|
|||
}
|
||||
|
||||
def uniform[T, D](tasks: Seq[Task[D]])(f: Seq[Result[D]] => Either[Task[T], T]): Node[Task, T] =
|
||||
toNode[T, ({ type l[L[x]] = List[L[D]] })#l](tasks.toList)(f)(AList.seq[D])
|
||||
toNode[T, λ[L[x] => List[L[D]]]](tasks.toList)(f)(AList.seq[D])
|
||||
|
||||
def toNode[T, k[L[x]]](inputs: k[Task])(f: k[Result] => Either[Task[T], T])(
|
||||
implicit a: AList[k]): Node[Task, T] = new Node[Task, T] {
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ trait TaskExtra {
|
|||
}
|
||||
|
||||
final implicit def multT2Task[A, B](in: (Task[A], Task[B])) =
|
||||
multInputTask[({ type l[L[x]] = (L[A], L[B]) })#l](in)(AList.tuple2[A, B])
|
||||
multInputTask[λ[L[x] => (L[A], L[B])]](in)(AList.tuple2[A, B])
|
||||
|
||||
final implicit def multInputTask[K[L[X]]](tasks: K[Task])(implicit a: AList[K]): MultiInTask[K] =
|
||||
new MultiInTask[K] {
|
||||
|
|
@ -248,7 +248,7 @@ object TaskExtra extends TaskExtra {
|
|||
}
|
||||
|
||||
def reducePair[S](a: Task[S], b: Task[S], f: (S, S) => S): Task[S] =
|
||||
multInputTask[({ type l[L[x]] = (L[S], L[S]) })#l]((a, b))(AList.tuple2[S, S]) map f.tupled
|
||||
multInputTask[λ[L[x] => (L[S], L[S])]]((a, b))(AList.tuple2[S, S]) map f.tupled
|
||||
|
||||
def anyFailM[K[L[x]]](implicit a: AList[K]): K[Result] => Seq[Incomplete] = in => {
|
||||
val incs = failuresM(a)(in)
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import sbt.internal.util.AList
|
|||
|
||||
object Test extends std.TaskExtra {
|
||||
def t2[A, B](a: Task[A], b: Task[B]) =
|
||||
multInputTask[({ type l[L[x]] = (L[A], L[B]) })#l]((a, b))(AList.tuple2)
|
||||
multInputTask[λ[L[x] => (L[A], L[B])]]((a, b))(AList.tuple2)
|
||||
def t3[A, B, C](a: Task[A], b: Task[B], c: Task[C]) =
|
||||
multInputTask[({ type l[L[x]] = (L[A], L[B], L[C]) })#l]((a, b, c))(AList.tuple3)
|
||||
multInputTask[λ[L[x] => (L[A], L[B], L[C])]]((a, b, c))(AList.tuple3)
|
||||
|
||||
val a = task(3)
|
||||
val b = task[Boolean](sys.error("test"))
|
||||
|
|
|
|||
|
|
@ -54,15 +54,16 @@ private[sbt] final class Execute[A[_] <: AnyRef](
|
|||
private[this] val reverse = idMap[A[_], Iterable[A[_]]]
|
||||
private[this] val callers = pMap[A, Compose[IDSet, A]#Apply]
|
||||
private[this] val state = idMap[A[_], State]
|
||||
private[this] val viewCache = pMap[A, ({ type l[t] = Node[A, t] })#l]
|
||||
private[this] val viewCache = pMap[A, Node[A, ?]]
|
||||
private[this] val results = pMap[A, Result]
|
||||
|
||||
private[this] val getResult: A ~> Result = new (A ~> Result) {
|
||||
def apply[T](a: A[T]): Result[T] = view.inline(a) match {
|
||||
case Some(v) => Value(v())
|
||||
case None => results(a)
|
||||
private[this] val getResult: A ~> Result = λ[A ~> Result](
|
||||
a =>
|
||||
view.inline(a) match {
|
||||
case Some(v) => Value(v())
|
||||
case None => results(a)
|
||||
}
|
||||
}
|
||||
)
|
||||
private[this] var progressState: progress.S = progress.initial
|
||||
|
||||
private[this] type State = State.Value
|
||||
|
|
|
|||
|
|
@ -28,12 +28,9 @@ final case class Value[+T](value: T) extends Result[T] {
|
|||
|
||||
object Result {
|
||||
type Id[X] = X
|
||||
val tryValue = new (Result ~> Id) {
|
||||
def apply[T](r: Result[T]): T =
|
||||
r match {
|
||||
case Value(v) => v
|
||||
case Inc(i) => throw i
|
||||
}
|
||||
val tryValue = λ[Result ~> Id] {
|
||||
case Value(v) => v
|
||||
case Inc(i) => throw i
|
||||
}
|
||||
def tryValues[S](r: Seq[Result[Unit]], v: Result[S]): S = {
|
||||
r foreach tryValue[Unit]
|
||||
|
|
|
|||
Loading…
Reference in New Issue