mirror of https://github.com/sbt/sbt.git
KeyMacro
This commit is contained in:
parent
0a38e296ad
commit
340721c4a1
|
|
@ -5,6 +5,7 @@ node_modules
|
|||
vscode-sbt-scala/client/server
|
||||
npm-debug.log
|
||||
*.vsix
|
||||
*_pid*.log
|
||||
!sbt/src/server-test/completions/target
|
||||
.big
|
||||
.idea
|
||||
|
|
|
|||
|
|
@ -182,8 +182,6 @@ val scriptedSbtReduxMimaSettings = Def.settings(mimaPreviousArtifacts := Set())
|
|||
lazy val sbtRoot: Project = (project in file("."))
|
||||
.aggregate(
|
||||
(allProjects diff Seq(
|
||||
actionsProj,
|
||||
mainSettingsProj,
|
||||
scriptedSbtReduxProj,
|
||||
scriptedSbtOldProj,
|
||||
scriptedPluginProj,
|
||||
|
|
|
|||
|
|
@ -99,7 +99,10 @@ trait Cont:
|
|||
case Right(r) => (r, faTpe)
|
||||
|
||||
// we can extract i out of i.type
|
||||
val instanceExpr = Expr.summon[Applicative[F]].get
|
||||
val instanceExpr =
|
||||
Expr
|
||||
.summon[Applicative[F]]
|
||||
.getOrElse(sys.error(s"Applicative[F] not found for ${fTypeCon.typeSymbol}"))
|
||||
val inputBuf = ListBuffer[Input]()
|
||||
|
||||
def makeApp(body: Term, inputs: List[Input]): Expr[F[Effect[A]]] = inputs match
|
||||
|
|
@ -111,7 +114,7 @@ trait Cont:
|
|||
def pure(body: Term): Expr[F[Effect[A]]] =
|
||||
def pure0[A1: Type](body: Expr[A1]): Expr[F[A1]] =
|
||||
'{
|
||||
$instanceExpr.pure[A1] { $body }
|
||||
$instanceExpr.pure[A1] { () => $body }
|
||||
}
|
||||
eitherTree match
|
||||
case Left(_) => pure0[Effect[A]](body.asExprOf[Effect[A]])
|
||||
|
|
|
|||
|
|
@ -14,20 +14,20 @@ import sbt.internal.util.Util.{ makeList, separate }
|
|||
|
||||
/**
|
||||
* A String parser that provides semi-automatic tab completion. A successful parse results in a
|
||||
* value of type `T`. The methods in this trait are what must be implemented to define a new Parser
|
||||
* value of type `A`. The methods in this trait are what must be implemented to define a new Parser
|
||||
* implementation, but are not typically useful for common usage. Instead, most useful methods for
|
||||
* combining smaller parsers into larger parsers are implicitly added by the [[RichParser]] type.
|
||||
*/
|
||||
trait Parser[+T] {
|
||||
def derive(i: Char): Parser[T]
|
||||
def resultEmpty: Result[T]
|
||||
def result: Option[T]
|
||||
trait Parser[+A1]:
|
||||
def derive(i: Char): Parser[A1]
|
||||
def resultEmpty: Result[A1]
|
||||
def result: Option[A1]
|
||||
def completions(level: Int): Completions
|
||||
def failure: Option[Failure]
|
||||
def isTokenStart = false
|
||||
def ifValid[S](p: => Parser[S]): Parser[S]
|
||||
def ifValid[A2](p: => Parser[A2]): Parser[A2]
|
||||
def valid: Boolean
|
||||
}
|
||||
end Parser
|
||||
|
||||
sealed trait RichParser[A] {
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ sealed trait RichParser[A] {
|
|||
}
|
||||
|
||||
/** Contains Parser implementation helper methods not typically needed for using parsers. */
|
||||
object Parser extends ParserMain {
|
||||
object Parser extends ParserMain:
|
||||
sealed abstract class Result[+T] {
|
||||
def isFailure: Boolean
|
||||
def isValid: Boolean
|
||||
|
|
@ -332,7 +332,8 @@ object Parser extends ParserMain {
|
|||
}
|
||||
|
||||
def and[T](a: Parser[T], b: Parser[_]): Parser[T] = a.ifValid(b.ifValid(new And(a, b)))
|
||||
}
|
||||
|
||||
end Parser
|
||||
|
||||
trait ParserMain {
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ object RelationTest extends Properties("Relation") {
|
|||
r._2s == _2s && r.reverseMap.keySet == _2s &&
|
||||
pairs.forall { case (a, b) =>
|
||||
(r.forward(a) contains b) &&
|
||||
(r.reverse(b) contains a) &&
|
||||
(r.forwardMap(a) contains b) &&
|
||||
(r.reverseMap(b) contains a)
|
||||
(r.reverse(b) contains a) &&
|
||||
(r.forwardMap(a) contains b) &&
|
||||
(r.reverseMap(b) contains a)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,9 +47,9 @@ object RelationTest extends Properties("Relation") {
|
|||
} &&
|
||||
all(removeFine) { case (a, b) =>
|
||||
("Forward does not contain removed" |: (!r.forward(a).contains(b))) &&
|
||||
("Reverse does not contain removed" |: (!r.reverse(b).contains(a))) &&
|
||||
("Forward map does not contain removed" |: (notIn(r.forwardMap, a, b))) &&
|
||||
("Reverse map does not contain removed" |: (notIn(r.reverseMap, b, a)))
|
||||
("Reverse does not contain removed" |: (!r.reverse(b).contains(a))) &&
|
||||
("Forward map does not contain removed" |: (notIn(r.forwardMap, a, b))) &&
|
||||
("Reverse map does not contain removed" |: (notIn(r.reverseMap, b, a)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,18 +16,18 @@ import sbt.internal.io.Source
|
|||
import sbt.internal.util.Attributed
|
||||
import sbt.io.{ AllPassFilter, NothingFilter }
|
||||
|
||||
object Append {
|
||||
@implicitNotFound("No Append.Value[${A}, ${B}] found, so ${B} cannot be appended to ${A}")
|
||||
trait Value[A, B] {
|
||||
def appendValue(a: A, b: B): A
|
||||
}
|
||||
object Append:
|
||||
@implicitNotFound("No Append.Value[${A1}, ${A2}] found, so ${A2} cannot be appended to ${A1}")
|
||||
trait Value[A1, A2]:
|
||||
def appendValue(a1: A1, a2: A2): A1
|
||||
end Value
|
||||
|
||||
@implicitNotFound("No Append.Values[${A}, ${B}] found, so ${B} cannot be appended to ${A}")
|
||||
trait Values[A, -B] {
|
||||
def appendValues(a: A, b: B): A
|
||||
}
|
||||
@implicitNotFound("No Append.Values[${A1}, ${A2}] found, so ${A2} cannot be appended to ${A1}")
|
||||
trait Values[A1, -A2]:
|
||||
def appendValues(a1: A1, a2: A2): A1
|
||||
end Values
|
||||
|
||||
trait Sequence[A, -B, T] extends Value[A, T] with Values[A, B]
|
||||
trait Sequence[A1, -A2, A3] extends Value[A1, A3] with Values[A1, A2]
|
||||
|
||||
implicit def appendSeq[T, V <: T]: Sequence[Seq[T], Seq[V], V] =
|
||||
new Sequence[Seq[T], Seq[V], V] {
|
||||
|
|
@ -35,11 +35,9 @@ object Append {
|
|||
def appendValue(a: Seq[T], b: V): Seq[T] = a :+ (b: T)
|
||||
}
|
||||
|
||||
implicit def appendSeqImplicit[T, V](implicit ev: V => T): Sequence[Seq[T], Seq[V], V] =
|
||||
new Sequence[Seq[T], Seq[V], V] {
|
||||
def appendValues(a: Seq[T], b: Seq[V]): Seq[T] = a ++ b.map(x => (x: T))
|
||||
def appendValue(a: Seq[T], b: V): Seq[T] = a :+ (b: T)
|
||||
}
|
||||
given appendSeqImplicit[A1, V](using ev: Conversion[V, A1]): Sequence[Seq[A1], Seq[V], V] with
|
||||
override def appendValues(a: Seq[A1], b: Seq[V]): Seq[A1] = a ++ b.map(x => (x: A1))
|
||||
override def appendValue(a: Seq[A1], b: V): Seq[A1] = a :+ (b: A1)
|
||||
|
||||
@compileTimeOnly("This can be used in += only.")
|
||||
implicit def appendTaskValueSeq[T, V <: T]: Value[Seq[Task[T]], Initialize[Task[V]]] =
|
||||
|
|
@ -54,17 +52,14 @@ object Append {
|
|||
def appendValue(a: List[T], b: V): List[T] = a :+ (b: T)
|
||||
}
|
||||
|
||||
implicit def appendListImplicit[T, V](implicit ev: V => T): Sequence[List[T], List[V], V] =
|
||||
new Sequence[List[T], List[V], V] {
|
||||
def appendValues(a: List[T], b: List[V]): List[T] = a ::: b.map(x => (x: T))
|
||||
def appendValue(a: List[T], b: V): List[T] = a :+ (b: T)
|
||||
}
|
||||
given appendListImplicit[A1, V](using ev: Conversion[V, A1]): Sequence[List[A1], List[V], V] with
|
||||
override def appendValues(a: List[A1], b: List[V]): List[A1] = a ++ b.map(x => (x: A1))
|
||||
override def appendValue(a: List[A1], b: V): List[A1] = a :+ (b: A1)
|
||||
|
||||
implicit def appendVectorImplicit[T, V](implicit ev: V => T): Sequence[Vector[T], Seq[V], V] =
|
||||
new Sequence[Vector[T], Seq[V], V] {
|
||||
def appendValues(a: Vector[T], b: Seq[V]): Vector[T] = a ++ b.map(x => (x: T))
|
||||
def appendValue(a: Vector[T], b: V): Vector[T] = a :+ (b: T)
|
||||
}
|
||||
given appendVectorImplicit[A1, V](using ev: Conversion[V, A1]): Sequence[Vector[A1], Vector[V], V]
|
||||
with
|
||||
override def appendValues(a: Vector[A1], b: Vector[V]): Vector[A1] = a ++ b.map(x => (x: A1))
|
||||
override def appendValue(a: Vector[A1], b: V): Vector[A1] = a :+ (b: A1)
|
||||
|
||||
// psst... these are implemented with SAM conversions
|
||||
implicit def appendString: Value[String, String] = _ + _
|
||||
|
|
@ -122,4 +117,4 @@ object Append {
|
|||
b
|
||||
}
|
||||
}
|
||||
}
|
||||
end Append
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ import sbt.KeyRanks.{ DTask, Invisible }
|
|||
import sbt.Scope.{ GlobalScope, ThisScope }
|
||||
import sbt.internal.util.Types.const
|
||||
import sbt.internal.util.complete.Parser
|
||||
import sbt.internal.util.{ Terminal => ITerminal, _ }
|
||||
import sbt.internal.util.{ Terminal => ITerminal, * }
|
||||
import Util._
|
||||
import sbt.util.Show
|
||||
import xsbti.VirtualFile
|
||||
|
||||
/** A concrete settings system that uses `sbt.Scope` for the scope type. */
|
||||
object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
|
||||
object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits:
|
||||
type Classpath = Seq[Attributed[File]]
|
||||
type VirtualClasspath = Seq[Attributed[VirtualFile]]
|
||||
|
||||
|
|
@ -57,16 +57,14 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
|
|||
current: ProjectRef,
|
||||
keyNameColor: Option[String] = None,
|
||||
): Show[ScopedKey[_]] =
|
||||
Show[ScopedKey[_]](
|
||||
key => {
|
||||
val color: String => String = withColor(_, keyNameColor)
|
||||
key.scope.extra.toOption
|
||||
.flatMap(_.get(Scope.customShowString).map(color))
|
||||
.getOrElse {
|
||||
Scope.display(key.scope, color(key.key.label), ref => displayRelative2(current, ref))
|
||||
}
|
||||
}
|
||||
)
|
||||
Show[ScopedKey[_]](key => {
|
||||
val color: String => String = withColor(_, keyNameColor)
|
||||
key.scope.extra.toOption
|
||||
.flatMap(_.get(Scope.customShowString).map(color))
|
||||
.getOrElse {
|
||||
Scope.display(key.scope, color(key.key.label), ref => displayRelative2(current, ref))
|
||||
}
|
||||
})
|
||||
|
||||
private[sbt] def showShortKey(
|
||||
keyNameColor: Option[String],
|
||||
|
|
@ -81,13 +79,12 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
|
|||
case _ => Reference.display(project) + trailing
|
||||
}
|
||||
}
|
||||
Show[ScopedKey[_]](
|
||||
key =>
|
||||
Scope.display(
|
||||
key.scope,
|
||||
withColor(key.key.label, keyNameColor),
|
||||
ref => displayShort(ref)
|
||||
)
|
||||
Show[ScopedKey[_]](key =>
|
||||
Scope.display(
|
||||
key.scope,
|
||||
withColor(key.key.label, keyNameColor),
|
||||
ref => displayShort(ref)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -103,13 +100,12 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
|
|||
currentBuild: URI,
|
||||
keyNameColor: Option[String] = None,
|
||||
): Show[ScopedKey[_]] =
|
||||
Show[ScopedKey[_]](
|
||||
key =>
|
||||
Scope.display(
|
||||
key.scope,
|
||||
withColor(key.key.label, keyNameColor),
|
||||
ref => displayBuildRelative(currentBuild, ref)
|
||||
)
|
||||
Show[ScopedKey[_]](key =>
|
||||
Scope.display(
|
||||
key.scope,
|
||||
withColor(key.key.label, keyNameColor),
|
||||
ref => displayBuildRelative(currentBuild, ref)
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
@ -181,18 +177,17 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
|
|||
|
||||
override def deriveAllowed[T](s: Setting[T], allowDynamic: Boolean): Option[String] =
|
||||
super.deriveAllowed(s, allowDynamic) orElse
|
||||
(if (s.key.scope != ThisScope)
|
||||
s"Scope cannot be defined for ${definedSettingString(s)}".some
|
||||
(if s.key.scope != ThisScope then
|
||||
Some(s"Scope cannot be defined for ${definedSettingString(s)}")
|
||||
else none) orElse
|
||||
s.dependencies
|
||||
.find(k => k.scope != ThisScope)
|
||||
.map(
|
||||
k =>
|
||||
s"Scope cannot be defined for dependency ${k.key.label} of ${definedSettingString(s)}"
|
||||
.map(k =>
|
||||
s"Scope cannot be defined for dependency ${k.key.label} of ${definedSettingString(s)}"
|
||||
)
|
||||
|
||||
override def intersect(s1: Scope, s2: Scope)(
|
||||
implicit delegates: Scope => Seq[Scope]
|
||||
override def intersect(s1: Scope, s2: Scope)(implicit
|
||||
delegates: Scope => Seq[Scope]
|
||||
): Option[Scope] =
|
||||
if (s2 == GlobalScope) Some(s1) // s1 is more specific
|
||||
else if (s1 == GlobalScope) Some(s2) // s2 is more specific
|
||||
|
|
@ -211,69 +206,71 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
|
|||
sbt.internal.util.complete.Parsers.spaceDelimited(argLabel)
|
||||
|
||||
/** Lifts the result of a setting initialization into a Task. */
|
||||
def toITask[T](i: Initialize[T]): Initialize[Task[T]] = map(i)(std.TaskExtra.inlineTask)
|
||||
def toITask[A1](i: Initialize[A1]): Initialize[Task[A1]] = map(i)(std.TaskExtra.inlineTask)
|
||||
|
||||
def toSParser[T](p: Parser[T]): State => Parser[T] = const(p)
|
||||
def toISParser[T](p: Initialize[Parser[T]]): Initialize[State => Parser[T]] = p(toSParser)
|
||||
def toIParser[T](p: Initialize[InputTask[T]]): Initialize[State => Parser[Task[T]]] = p(_.parser)
|
||||
|
||||
import std.SettingMacro.{ settingDynMacroImpl, settingMacroImpl }
|
||||
// import std.SettingMacro.{ settingDynMacroImpl, settingMacroImpl }
|
||||
import std.TaskMacro.{
|
||||
inputTaskDynMacroImpl,
|
||||
inputTaskMacroImpl,
|
||||
taskDynMacroImpl,
|
||||
taskIfMacroImpl,
|
||||
taskMacroImpl
|
||||
// inputTaskDynMacroImpl,
|
||||
// inputTaskMacroImpl,
|
||||
// taskDynMacroImpl,
|
||||
// taskIfMacroImpl,
|
||||
taskMacroImpl,
|
||||
}
|
||||
import std._
|
||||
|
||||
import language.experimental.macros
|
||||
|
||||
def task[T](t: T): Def.Initialize[Task[T]] = macro taskMacroImpl[T]
|
||||
def taskDyn[T](t: Def.Initialize[Task[T]]): Def.Initialize[Task[T]] = macro taskDynMacroImpl[T]
|
||||
def setting[T](t: T): Def.Initialize[T] = macro settingMacroImpl[T]
|
||||
def settingDyn[T](t: Def.Initialize[T]): Def.Initialize[T] = macro settingDynMacroImpl[T]
|
||||
def inputTask[T](t: T): Def.Initialize[InputTask[T]] = macro inputTaskMacroImpl[T]
|
||||
def inputTaskDyn[T](t: Def.Initialize[Task[T]]): Def.Initialize[InputTask[T]] =
|
||||
macro inputTaskDynMacroImpl[T]
|
||||
def taskIf[T](a: T): Def.Initialize[Task[T]] = macro taskIfMacroImpl[T]
|
||||
inline def task[A1](inline a1: A1): Def.Initialize[Task[A1]] =
|
||||
${ taskMacroImpl[A1]('a1) }
|
||||
|
||||
private[sbt] def selectITask[A, B](
|
||||
fab: Initialize[Task[Either[A, B]]],
|
||||
fin: Initialize[Task[A => B]]
|
||||
): Initialize[Task[B]] =
|
||||
// def taskDyn[T](t: Def.Initialize[Task[T]]): Def.Initialize[Task[T]] = macro taskDynMacroImpl[T]
|
||||
// def setting[T](t: T): Def.Initialize[T] = macro settingMacroImpl[T]
|
||||
// def settingDyn[T](t: Def.Initialize[T]): Def.Initialize[T] = macro settingDynMacroImpl[T]
|
||||
// def inputTask[T](t: T): Def.Initialize[InputTask[T]] = macro inputTaskMacroImpl[T]
|
||||
// def inputTaskDyn[T](t: Def.Initialize[Task[T]]): Def.Initialize[InputTask[T]] = {
|
||||
// macro inputTaskDynMacroImpl[T]
|
||||
// }
|
||||
// def taskIf[T](a: T): Def.Initialize[Task[T]] = macro taskIfMacroImpl[T]
|
||||
|
||||
private[sbt] def selectITask[A1, A2](
|
||||
fab: Initialize[Task[Either[A1, A2]]],
|
||||
fin: Initialize[Task[A1 => A2]]
|
||||
): Initialize[Task[A2]] =
|
||||
fab.zipWith(fin)((ab, in) => TaskExtra.select(ab, in))
|
||||
|
||||
import Scoped.syntax._
|
||||
import Scoped.syntax.* // { Def => _, DTask => _, Invisible => _, * }
|
||||
|
||||
// derived from select
|
||||
private[sbt] def branchS[A, B, C](
|
||||
x: Def.Initialize[Task[Either[A, B]]]
|
||||
)(l: Def.Initialize[Task[A => C]])(r: Def.Initialize[Task[B => C]]): Def.Initialize[Task[C]] = {
|
||||
val lhs = {
|
||||
)(l: Def.Initialize[Task[A => C]])(r: Def.Initialize[Task[B => C]]): Def.Initialize[Task[C]] =
|
||||
val lhs: Initialize[Task[Either[B, C]]] = {
|
||||
val innerLhs: Def.Initialize[Task[Either[A, Either[B, C]]]] =
|
||||
x.map((fab: Either[A, B]) => fab.map(Left(_)))
|
||||
val innerRhs: Def.Initialize[Task[A => Either[B, C]]] =
|
||||
l.map((fn: A => C) => fn.andThen(Right(_)))
|
||||
selectITask(innerLhs, innerRhs)
|
||||
selectITask[A, Either[B, C]](innerLhs, innerRhs)
|
||||
}
|
||||
selectITask(lhs, r)
|
||||
}
|
||||
selectITask[B, C](lhs, r)
|
||||
|
||||
// derived from select
|
||||
def ifS[A](
|
||||
x: Def.Initialize[Task[Boolean]]
|
||||
)(t: Def.Initialize[Task[A]])(e: Def.Initialize[Task[A]]): Def.Initialize[Task[A]] = {
|
||||
)(t: Def.Initialize[Task[A]])(e: Def.Initialize[Task[A]]): Def.Initialize[Task[A]] =
|
||||
val condition: Def.Initialize[Task[Either[Unit, Unit]]] =
|
||||
x.map((p: Boolean) => if (p) Left(()) else Right(()))
|
||||
x.map { (p: Boolean) => if p then Left(()) else Right(()) }
|
||||
val left: Def.Initialize[Task[Unit => A]] =
|
||||
t.map((a: A) => { _ => a })
|
||||
t.map { (a: A) => { (_: Unit) => a } }
|
||||
val right: Def.Initialize[Task[Unit => A]] =
|
||||
e.map((a: A) => { _ => a })
|
||||
e.map { (a: A) => { (_: Unit) => a } }
|
||||
branchS(condition)(left)(right)
|
||||
}
|
||||
|
||||
/** Returns `PromiseWrap[A]`, which is a wrapper around `scala.concurrent.Promise`.
|
||||
/**
|
||||
* Returns `PromiseWrap[A]`, which is a wrapper around `scala.concurrent.Promise`.
|
||||
* When a task is typed promise (e.g. `Def.Initialize[Task[PromiseWrap[A]]]`),an implicit
|
||||
* method called `await` is injected which will run in a thread outside of concurrent restriction budget.
|
||||
*/
|
||||
|
|
@ -282,35 +279,40 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
|
|||
// The following conversions enable the types Initialize[T], Initialize[Task[T]], and Task[T] to
|
||||
// be used in task and setting macros as inputs with an ultimate result of type T
|
||||
|
||||
implicit def macroValueI[T](@deprecated("unused", "") in: Initialize[T]): MacroValue[T] = ???
|
||||
// implicit def macroValueI[T](@deprecated("unused", "") in: Initialize[T]): MacroValue[T] = ???
|
||||
|
||||
implicit def macroValueIT[T](@deprecated("unused", "") in: Initialize[Task[T]]): MacroValue[T] =
|
||||
???
|
||||
// implicit def macroValueIT[T](@deprecated("unused", "") in: Initialize[Task[T]]): MacroValue[T] =
|
||||
// ???
|
||||
|
||||
implicit def macroValueIInT[T](
|
||||
@deprecated("unused", "") in: Initialize[InputTask[T]]
|
||||
): InputEvaluated[T] = ???
|
||||
// implicit def macroValueIInT[T](
|
||||
// @deprecated("unused", "") in: Initialize[InputTask[T]]
|
||||
// ): InputEvaluated[T] = ???
|
||||
|
||||
implicit def taskMacroValueIT[T](
|
||||
@deprecated("unused", "") in: Initialize[Task[T]]
|
||||
): MacroTaskValue[T] = ???
|
||||
// implicit def taskMacroValueIT[T](
|
||||
// @deprecated("unused", "") in: Initialize[Task[T]]
|
||||
// ): MacroTaskValue[T] = ???
|
||||
|
||||
implicit def macroPrevious[T](@deprecated("unused", "") in: TaskKey[T]): MacroPrevious[T] = ???
|
||||
// implicit def macroPrevious[T](@deprecated("unused", "") in: TaskKey[T]): MacroPrevious[T] = ???
|
||||
|
||||
// The following conversions enable the types Parser[T], Initialize[Parser[T]], and
|
||||
// Initialize[State => Parser[T]] to be used in the inputTask macro as an input with an ultimate
|
||||
// result of type T
|
||||
implicit def parserInitToInput[T](
|
||||
@deprecated("unused", "") p: Initialize[Parser[T]]
|
||||
): ParserInput[T] = ???
|
||||
// implicit def parserInitToInput[T](
|
||||
// @deprecated("unused", "") p: Initialize[Parser[T]]
|
||||
// ): ParserInput[T] = ???
|
||||
|
||||
implicit def parserInitStateToInput[T](
|
||||
@deprecated("unused", "") p: Initialize[State => Parser[T]]
|
||||
): ParserInput[T] = ???
|
||||
// implicit def parserInitStateToInput[T](
|
||||
// @deprecated("unused", "") p: Initialize[State => Parser[T]]
|
||||
// ): ParserInput[T] = ???
|
||||
|
||||
def settingKey[T](description: String): SettingKey[T] = macro std.KeyMacro.settingKeyImpl[T]
|
||||
def taskKey[T](description: String): TaskKey[T] = macro std.KeyMacro.taskKeyImpl[T]
|
||||
def inputKey[T](description: String): InputKey[T] = macro std.KeyMacro.inputKeyImpl[T]
|
||||
inline def settingKey[A1](inline description: String): SettingKey[A1] =
|
||||
${ std.KeyMacro.settingKeyImpl[A1]('description) }
|
||||
|
||||
inline def taskKey[A1](inline description: String): TaskKey[A1] =
|
||||
${ std.KeyMacro.taskKeyImpl[A1]('description) }
|
||||
|
||||
inline def inputKey[A1](inline description: String): InputKey[A1] =
|
||||
${ std.KeyMacro.inputKeyImpl[A1]('description) }
|
||||
|
||||
class InitOps[T](private val x: Initialize[T]) extends AnyVal {
|
||||
def toTaskable: Taskable[T] = x
|
||||
|
|
@ -320,7 +322,8 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
|
|||
def toTaskable: Taskable[T] = x
|
||||
}
|
||||
|
||||
/** This works around Scala 2.12.12's
|
||||
/**
|
||||
* This works around Scala 2.12.12's
|
||||
* "a pure expression does nothing in statement position"
|
||||
*
|
||||
* {{{
|
||||
|
|
@ -330,8 +333,8 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
|
|||
*/
|
||||
def unit(a: Any): Unit = ()
|
||||
|
||||
private[sbt] def dummy[T: Manifest](name: String, description: String): (TaskKey[T], Task[T]) =
|
||||
(TaskKey[T](name, description, DTask), dummyTask(name))
|
||||
private[sbt] def dummy[A: Manifest](name: String, description: String): (TaskKey[A], Task[A]) =
|
||||
(TaskKey[A](name, description, DTask), dummyTask(name))
|
||||
|
||||
private[sbt] def dummyTask[T](name: String): Task[T] = {
|
||||
import std.TaskExtra.{ task => newTask, _ }
|
||||
|
|
@ -350,27 +353,32 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
|
|||
Invisible
|
||||
)
|
||||
|
||||
private[sbt] val (stateKey, dummyState) = dummy[State]("state", "Current build state.")
|
||||
private[sbt] val (stateKey: TaskKey[State], dummyState: Task[State]) =
|
||||
dummy[State]("state", "Current build state.")
|
||||
|
||||
private[sbt] val (streamsManagerKey, dummyStreamsManager) = Def.dummy[std.Streams[ScopedKey[_]]](
|
||||
"streams-manager",
|
||||
"Streams manager, which provides streams for different contexts."
|
||||
)
|
||||
}
|
||||
private[sbt] val (
|
||||
streamsManagerKey: TaskKey[std.Streams[ScopedKey[_]]],
|
||||
dummyStreamsManager: Task[std.Streams[ScopedKey[_]]]
|
||||
) =
|
||||
Def.dummy[std.Streams[ScopedKey[_]]](
|
||||
"streams-manager",
|
||||
"Streams manager, which provides streams for different contexts."
|
||||
)
|
||||
end Def
|
||||
|
||||
// these need to be mixed into the sbt package object
|
||||
// because the target doesn't involve Initialize or anything in Def
|
||||
trait TaskMacroExtra {
|
||||
implicit def macroValueT[T](@deprecated("unused", "") in: Task[T]): std.MacroValue[T] = ???
|
||||
// implicit def macroValueT[T](@deprecated("unused", "") in: Task[T]): std.MacroValue[T] = ???
|
||||
|
||||
implicit def macroValueIn[T](@deprecated("unused", "") in: InputTask[T]): std.InputEvaluated[T] =
|
||||
???
|
||||
// implicit def macroValueIn[T](@deprecated("unused", "") in: InputTask[T]): std.InputEvaluated[T] =
|
||||
// ???
|
||||
|
||||
implicit def parserToInput[T](@deprecated("unused", "") in: Parser[T]): std.ParserInput[T] = ???
|
||||
// implicit def parserToInput[T](@deprecated("unused", "") in: Parser[T]): std.ParserInput[T] = ???
|
||||
|
||||
implicit def stateParserToInput[T](
|
||||
@deprecated("unused", "") in: State => Parser[T]
|
||||
): std.ParserInput[T] = ???
|
||||
// implicit def stateParserToInput[T](
|
||||
// @deprecated("unused", "") in: State => Parser[T]
|
||||
// ): std.ParserInput[T] = ???
|
||||
}
|
||||
|
||||
sealed trait InitializeImplicits0 { self: Def.type =>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ private final class DelegateIndex0(refs: Map[ProjectRef, ProjectDelegates]) exte
|
|||
case Some(pd) =>
|
||||
pd.confs.get(conf) match {
|
||||
case Some(cs) => cs
|
||||
case None => (Select(conf): ScopeAxis[ConfigKey]) :: (Zero: ScopeAxis[ConfigKey]) :: Nil
|
||||
case None => (Select(conf): ScopeAxis[ConfigKey]) :: (Zero: ScopeAxis[ConfigKey]) :: Nil
|
||||
}
|
||||
case None => (Select(conf): ScopeAxis[ConfigKey]) :: (Zero: ScopeAxis[ConfigKey]) :: Nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,25 +15,25 @@ import sbt.internal.util.Types._
|
|||
import sbt.internal.util.Util._
|
||||
|
||||
/** Parses input and produces a task to run. Constructed using the companion object. */
|
||||
final class InputTask[T] private (val parser: State => Parser[Task[T]]) {
|
||||
def mapTask[S](f: Task[T] => Task[S]): InputTask[S] =
|
||||
new InputTask[S](s => parser(s) map f)
|
||||
final class InputTask[A1] private (val parser: State => Parser[Task[A1]]):
|
||||
def mapTask[S](f: Task[A1] => Task[S]): InputTask[S] =
|
||||
InputTask[S](s => parser(s) map f)
|
||||
|
||||
def partialInput(in: String): InputTask[T] =
|
||||
new InputTask[T](s => Parser(parser(s))(in))
|
||||
def partialInput(in: String): InputTask[A1] =
|
||||
InputTask[A1](s => Parser(parser(s))(in))
|
||||
|
||||
def fullInput(in: String): InputTask[T] =
|
||||
new InputTask[T](
|
||||
s =>
|
||||
Parser.parse(in, parser(s)) match {
|
||||
case Right(v) => Parser.success(v)
|
||||
case Left(msg) =>
|
||||
val indented = msg.linesIterator.map(" " + _).mkString("\n")
|
||||
Parser.failure(s"Invalid programmatic input:\n$indented")
|
||||
}
|
||||
def fullInput(in: String): InputTask[A1] =
|
||||
InputTask[A1](s =>
|
||||
Parser.parse(in, parser(s)) match {
|
||||
case Right(v) => Parser.success(v)
|
||||
case Left(msg) =>
|
||||
val indented = msg.linesIterator.map(" " + _).mkString("\n")
|
||||
Parser.failure(s"Invalid programmatic input:\n$indented")
|
||||
}
|
||||
)
|
||||
}
|
||||
end InputTask
|
||||
|
||||
/*
|
||||
object InputTask {
|
||||
implicit class InitializeInput[T](i: Initialize[InputTask[T]]) {
|
||||
def partialInput(in: String): Initialize[InputTask[T]] = i(_ partialInput in)
|
||||
|
|
@ -41,17 +41,15 @@ object InputTask {
|
|||
|
||||
import std.FullInstance._
|
||||
def toTask(in: String): Initialize[Task[T]] = flatten(
|
||||
(Def.stateKey zipWith i)(
|
||||
(sTask, it) =>
|
||||
sTask map (
|
||||
s =>
|
||||
Parser.parse(in, it.parser(s)) match {
|
||||
case Right(t) => Def.value(t)
|
||||
case Left(msg) =>
|
||||
val indented = msg.linesIterator.map(" " + _).mkString("\n")
|
||||
sys.error(s"Invalid programmatic input:\n$indented")
|
||||
}
|
||||
)
|
||||
(Def.stateKey zipWith i)((sTask, it) =>
|
||||
sTask map (s =>
|
||||
Parser.parse(in, it.parser(s)) match {
|
||||
case Right(t) => Def.value(t)
|
||||
case Left(msg) =>
|
||||
val indented = msg.linesIterator.map(" " + _).mkString("\n")
|
||||
sys.error(s"Invalid programmatic input:\n$indented")
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -91,24 +89,24 @@ object InputTask {
|
|||
}
|
||||
|
||||
/**
|
||||
* Constructs an InputTask from:
|
||||
* a) a Parser constructed using other Settings, but not Tasks
|
||||
* b) a dynamically constructed Task that uses Settings, Tasks, and the result of parsing.
|
||||
*/
|
||||
* Constructs an InputTask from:
|
||||
* a) a Parser constructed using other Settings, but not Tasks
|
||||
* b) a dynamically constructed Task that uses Settings, Tasks, and the result of parsing.
|
||||
*/
|
||||
def createDyn[I, T](
|
||||
p: Initialize[State => Parser[I]]
|
||||
)(action: Initialize[Task[I => Initialize[Task[T]]]]): Initialize[InputTask[T]] =
|
||||
separate(p)(std.FullInstance.flattenFun[I, T](action))
|
||||
|
||||
/** A dummy parser that consumes no input and produces nothing useful (unit).*/
|
||||
/** A dummy parser that consumes no input and produces nothing useful (unit). */
|
||||
def emptyParser: State => Parser[Unit] =
|
||||
Types.const(sbt.internal.util.complete.DefaultParsers.success(()))
|
||||
|
||||
/** Implementation detail that is public because it is used by a macro.*/
|
||||
/** Implementation detail that is public because it is used by a macro. */
|
||||
def parserAsInput[T](p: Parser[T]): Initialize[State => Parser[T]] =
|
||||
Def.valueStrict(Types.const(p))
|
||||
|
||||
/** Implementation detail that is public because it is used by a macro.*/
|
||||
/** Implementation detail that is public because it is used by a macro. */
|
||||
def initParserAsInput[T](i: Initialize[Parser[T]]): Initialize[State => Parser[T]] =
|
||||
i(Types.const[State, Parser[T]])
|
||||
|
||||
|
|
@ -126,10 +124,10 @@ object InputTask {
|
|||
}
|
||||
|
||||
/**
|
||||
* The proper solution is to have a Manifest context bound and accept slight source incompatibility,
|
||||
* The affected InputTask construction methods are all deprecated and so it is better to keep complete
|
||||
* compatibility. Because the AttributeKey is local, it uses object equality and the manifest is not used.
|
||||
*/
|
||||
* The proper solution is to have a Manifest context bound and accept slight source incompatibility,
|
||||
* The affected InputTask construction methods are all deprecated and so it is better to keep complete
|
||||
* compatibility. Because the AttributeKey is local, it uses object equality and the manifest is not used.
|
||||
*/
|
||||
private[this] def localKey[T]: AttributeKey[T] =
|
||||
AttributeKey.local[Unit].asInstanceOf[AttributeKey[T]]
|
||||
|
||||
|
|
@ -170,10 +168,10 @@ object InputTask {
|
|||
val newTask = Task(t.info, newAction)
|
||||
seen.put(t, newTask)
|
||||
newTask
|
||||
} else
|
||||
t0.asInstanceOf[Task[A]]
|
||||
} else t0.asInstanceOf[Task[A]]
|
||||
}
|
||||
}
|
||||
f(task)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -47,13 +47,15 @@ object Previous {
|
|||
private final val StreamName = "previous"
|
||||
private[sbt] final val DependencyDirectory = "previous-dependencies"
|
||||
|
||||
/** Represents a reference task.previous*/
|
||||
/** Represents a reference task.previous */
|
||||
private[sbt] final class Referenced[T](val key: Key[T], val format: JsonFormat[T]) {
|
||||
def this(task: ScopedTaskKey[T], format: JsonFormat[T]) = this(Key(task, task), format)
|
||||
@deprecated("unused", "1.3.0")
|
||||
private[sbt] def task: ScopedKey[Task[T]] = key.task
|
||||
|
||||
// @deprecated("unused", "1.3.0")
|
||||
// private[sbt] def task: ScopedKey[Task[T]] = key.task
|
||||
|
||||
lazy val stamped: JsonFormat[T] =
|
||||
StampedFormat.withStamp(key.task.key.manifest.toString)(format)
|
||||
StampedFormat.withStamp(key.task.key.classTag.toString)(format)
|
||||
def setTask(newTask: ScopedKey[Task[T]]) = new Referenced(newTask, format)
|
||||
private[sbt] def read(streams: Streams): Option[T] =
|
||||
try Option(streams(key.cacheKey).cacheStoreFactory.make(StreamName).read[T]()(stamped))
|
||||
|
|
@ -82,7 +84,7 @@ object Previous {
|
|||
else {
|
||||
val am = enclosing.scope.extra match {
|
||||
case Select(a) => a.put(scopedKeyAttribute, task.asInstanceOf[AnyTaskKey])
|
||||
case _ => AttributeMap.empty.put(scopedKeyAttribute, task.asInstanceOf[AnyTaskKey])
|
||||
case _ => AttributeMap.empty.put(scopedKeyAttribute, task.asInstanceOf[AnyTaskKey])
|
||||
}
|
||||
Def.ScopedKey(enclosing.scope.copy(extra = Select(am)), enclosing.key)
|
||||
}
|
||||
|
|
@ -120,7 +122,7 @@ object Previous {
|
|||
// We first collect all of the successful tasks and write their scoped key into a map
|
||||
// along with their values.
|
||||
val successfulTaskResults = (for {
|
||||
results.TPair(task, Value(v)) <- results.toTypedSeq
|
||||
results.TPair(task, Result.Value(v)) <- results.toTypedSeq
|
||||
key <- task.info.attributes.get(Def.taskDefinitionKey).asInstanceOf[Option[AnyTaskKey]]
|
||||
} yield key -> v).toMap
|
||||
// We then traverse the successful results and look up all of the referenced values for
|
||||
|
|
@ -147,28 +149,27 @@ object Previous {
|
|||
|
||||
/** Public as a macro implementation detail. Do not call directly. */
|
||||
def runtime[T](skey: TaskKey[T])(implicit format: JsonFormat[T]): Initialize[Task[Option[T]]] = {
|
||||
val inputs = (Global / cache) zip Def.validated(skey, selfRefOk = true) zip (Global / references)
|
||||
inputs {
|
||||
case ((prevTask, resolved), refs) =>
|
||||
val key = Key(resolved, resolved)
|
||||
refs.recordReference(key, format) // always evaluated on project load
|
||||
prevTask.map(_.get(key)) // evaluated if this task is evaluated
|
||||
val inputs =
|
||||
(Global / cache) zip Def.validated(skey, selfRefOk = true) zip (Global / references)
|
||||
inputs { case ((prevTask, resolved), refs) =>
|
||||
val key = Key(resolved, resolved)
|
||||
refs.recordReference(key, format) // always evaluated on project load
|
||||
prevTask.map(_.get(key)) // evaluated if this task is evaluated
|
||||
}
|
||||
}
|
||||
|
||||
/** Public as a macro implementation detail. Do not call directly. */
|
||||
def runtimeInEnclosingTask[T](skey: TaskKey[T])(
|
||||
implicit format: JsonFormat[T]
|
||||
def runtimeInEnclosingTask[T](skey: TaskKey[T])(implicit
|
||||
format: JsonFormat[T]
|
||||
): Initialize[Task[Option[T]]] = {
|
||||
val inputs = (Global / cache)
|
||||
.zip(Def.validated(skey, selfRefOk = true))
|
||||
.zip(Global / references)
|
||||
.zip(Def.resolvedScoped)
|
||||
inputs {
|
||||
case (((prevTask, resolved), refs), inTask: ScopedKey[Task[_]] @unchecked) =>
|
||||
val key = Key(resolved, inTask)
|
||||
refs.recordReference(key, format) // always evaluated on project load
|
||||
prevTask.map(_.get(key)) // evaluated if this task is evaluated
|
||||
inputs { case (((prevTask, resolved), refs), inTask: ScopedKey[Task[_]] @unchecked) =>
|
||||
val key = Key(resolved, inTask)
|
||||
refs.recordReference(key, format) // always evaluated on project load
|
||||
prevTask.map(_.get(key)) // evaluated if this task is evaluated
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@ package sbt
|
|||
|
||||
import scala.concurrent.{ Promise => XPromise }
|
||||
|
||||
final class PromiseWrap[A] {
|
||||
final class PromiseWrap[A]:
|
||||
private[sbt] val underlying: XPromise[A] = XPromise()
|
||||
def complete(result: Result[A]): Unit =
|
||||
result match {
|
||||
case Inc(cause) => underlying.failure(cause)
|
||||
case Value(value) => underlying.success(value)
|
||||
case Result.Inc(cause) => underlying.failure(cause)
|
||||
case Result.Value(value) => underlying.success(value)
|
||||
}
|
||||
def success(value: A): Unit = underlying.success(value)
|
||||
def failure(cause: Throwable): Unit = underlying.failure(cause)
|
||||
def isCompleted: Boolean = underlying.isCompleted
|
||||
}
|
||||
end PromiseWrap
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ object ProjectRef {
|
|||
}
|
||||
object RootProject {
|
||||
|
||||
/** Reference to the root project at 'base'.*/
|
||||
/** Reference to the root project at 'base'. */
|
||||
def apply(base: File): RootProject = RootProject(IO toURI base)
|
||||
}
|
||||
object Reference {
|
||||
|
|
@ -96,7 +96,7 @@ object Reference {
|
|||
case ProjectRef(b, _) => b
|
||||
}
|
||||
|
||||
/** Extracts the build URI from a Reference if one has been explicitly defined.*/
|
||||
/** Extracts the build URI from a Reference if one has been explicitly defined. */
|
||||
def uri(ref: Reference): Option[URI] = ref match {
|
||||
case RootProject(b) => Some(b)
|
||||
case ProjectRef(b, _) => Some(b)
|
||||
|
|
|
|||
|
|
@ -408,9 +408,8 @@ object Scope {
|
|||
projectInherit: ProjectRef => Seq[ProjectRef],
|
||||
configInherit: (ResolvedReference, ConfigKey) => Seq[ConfigKey]
|
||||
): DelegateIndex = {
|
||||
val pDelegates = refs map {
|
||||
case (ref, project) =>
|
||||
(ref, delegateIndex(ref, configurations(project))(projectInherit, configInherit))
|
||||
val pDelegates = refs map { case (ref, project) =>
|
||||
(ref, delegateIndex(ref, configurations(project))(projectInherit, configInherit))
|
||||
} toMap;
|
||||
new DelegateIndex0(pDelegates)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,13 @@ trait SlashSyntax {
|
|||
implicit def sbtSlashSyntaxRichReferenceAxis(a: ScopeAxis[Reference]): RichReference =
|
||||
new RichReference(Scope(a, This, This, This))
|
||||
|
||||
implicit def sbtSlashSyntaxRichReference(r: Reference): RichReference = Select(r)
|
||||
implicit def sbtSlashSyntaxRichProject[A](p: A)(implicit x: A => Reference): RichReference =
|
||||
(p: Reference)
|
||||
// implicit def sbtSlashSyntaxRichReference(r: Reference): RichReference = Select(r)
|
||||
|
||||
given sbtSlashSyntaxRichReference: Conversion[Reference, RichReference] =
|
||||
(r: Reference) => Select(r)
|
||||
|
||||
given sbtSlashSyntaxRichProject[A](using Conversion[A, Reference]): Conversion[A, RichReference] =
|
||||
(a: A) => Select(a: Reference)
|
||||
|
||||
implicit def sbtSlashSyntaxRichConfigKey(c: ConfigKey): RichConfiguration =
|
||||
new RichConfiguration(Scope(This, Select(c), This, This))
|
||||
|
|
@ -62,7 +66,7 @@ object SlashSyntax {
|
|||
sealed trait HasSlashKey {
|
||||
protected def scope: Scope
|
||||
@nowarn
|
||||
final def /[K](key: Scoped.ScopingSetting[K]): K = key in scope
|
||||
final def /[K](key: Scoped.ScopingSetting[K]): K = key.in(scope)
|
||||
}
|
||||
|
||||
sealed trait HasSlashKeyOrAttrKey extends HasSlashKey {
|
||||
|
|
|
|||
|
|
@ -13,40 +13,40 @@ import sbt.internal.util.Types._
|
|||
import sbt.internal.util.{ ~>, AList, AttributeKey, Settings, SourcePosition }
|
||||
import sbt.util.OptJsonWriter
|
||||
import sbt.ConcurrentRestrictions.Tag
|
||||
import sbt.Def.{ Initialize, KeyedInitialize, ScopedKey, Setting, setting }
|
||||
import sbt.Def.{ Initialize, ScopedKey, Setting, setting }
|
||||
import std.TaskExtra.{ task => mktask, _ }
|
||||
|
||||
/** An abstraction on top of Settings for build configuration and task definition. */
|
||||
sealed trait Scoped extends Equals {
|
||||
sealed trait Scoped extends Equals:
|
||||
def scope: Scope
|
||||
val key: AttributeKey[_]
|
||||
|
||||
override def equals(that: Any) =
|
||||
override def equals(that: Any): Boolean =
|
||||
(this eq that.asInstanceOf[AnyRef]) || (that match {
|
||||
case that: Scoped => scope == that.scope && key == that.key && canEqual(that)
|
||||
case _ => false
|
||||
})
|
||||
|
||||
override def hashCode() = (scope, key).##
|
||||
}
|
||||
override def hashCode(): Int = (scope, key).##
|
||||
end Scoped
|
||||
|
||||
/** A SettingKey, TaskKey or `Initialize[Task]` that can be converted into an `Initialize[Task]`. */
|
||||
sealed trait Taskable[T] {
|
||||
def toTask: Initialize[Task[T]]
|
||||
}
|
||||
sealed trait Taskable[A]:
|
||||
def toTask: Initialize[Task[A]]
|
||||
end Taskable
|
||||
|
||||
sealed trait TaskableImplicits { self: Taskable.type =>
|
||||
implicit def fromInit[T](x: Initialize[T]): Taskable[T] =
|
||||
new Taskable[T] { def toTask = Def.toITask(x) }
|
||||
implicit def fromInit[A](x: Initialize[A]): Taskable[A] =
|
||||
new Taskable[A] { def toTask = Def.toITask(x) }
|
||||
}
|
||||
|
||||
object Taskable extends TaskableImplicits {
|
||||
implicit def fromITask[T](x: Initialize[Task[T]]): Taskable[T] =
|
||||
new Taskable[T] { def toTask = x }
|
||||
implicit def fromITask[A](x: Initialize[Task[A]]): Taskable[A] =
|
||||
new Taskable[A] { def toTask = x }
|
||||
}
|
||||
|
||||
/** A common type for SettingKey and TaskKey so that both can be used as inputs to tasks.*/
|
||||
sealed trait ScopedTaskable[T] extends Scoped with Taskable[T]
|
||||
/** A common type for SettingKey and TaskKey so that both can be used as inputs to tasks. */
|
||||
sealed trait ScopedTaskable[A] extends Scoped with Taskable[A]
|
||||
|
||||
/**
|
||||
* Identifies a setting. It consists of three parts: the scope, the name, and the type of a value associated with this key.
|
||||
|
|
@ -54,72 +54,72 @@ sealed trait ScopedTaskable[T] extends Scoped with Taskable[T]
|
|||
* The name and the type are represented by a value of type `AttributeKey[T]`.
|
||||
* Instances are constructed using the companion object.
|
||||
*/
|
||||
sealed abstract class SettingKey[T]
|
||||
extends ScopedTaskable[T]
|
||||
with KeyedInitialize[T]
|
||||
with Scoped.ScopingSetting[SettingKey[T]]
|
||||
with Scoped.DefinableSetting[T] {
|
||||
sealed abstract class SettingKey[A1]
|
||||
extends ScopedTaskable[A1]
|
||||
with Def.KeyedInitialize[A1]
|
||||
with Scoped.ScopingSetting[SettingKey[A1]]
|
||||
with Scoped.DefinableSetting[A1]:
|
||||
|
||||
val key: AttributeKey[T]
|
||||
val key: AttributeKey[A1]
|
||||
|
||||
override def toString: String = s"SettingKey($scope / $key)"
|
||||
|
||||
final def toTask: Initialize[Task[T]] = this apply inlineTask
|
||||
final def toTask: Initialize[Task[A1]] = this apply inlineTask
|
||||
|
||||
final def scopedKey: ScopedKey[T] = ScopedKey(scope, key)
|
||||
final def scopedKey: ScopedKey[A1] = ScopedKey(scope, key)
|
||||
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
final def in(scope: Scope): SettingKey[T] =
|
||||
final def in(scope: Scope): SettingKey[A1] =
|
||||
Scoped.scopedSetting(Scope.replaceThis(this.scope)(scope), this.key)
|
||||
|
||||
final def :=(v: T): Setting[T] = macro std.TaskMacro.settingAssignMacroImpl[T]
|
||||
// final def :=(v: T): Setting[T] = macro std.TaskMacro.settingAssignMacroImpl[T]
|
||||
|
||||
final def +=[U](v: U)(implicit a: Append.Value[T, U]): Setting[T] =
|
||||
macro std.TaskMacro.settingAppend1Impl[T, U]
|
||||
// final def +=[U](v: U)(implicit a: Append.Value[T, U]): Setting[T] =
|
||||
// macro std.TaskMacro.settingAppend1Impl[T, U]
|
||||
|
||||
final def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[T] =
|
||||
macro std.TaskMacro.settingAppendNImpl[T, U]
|
||||
// final def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[T] =
|
||||
// macro std.TaskMacro.settingAppendNImpl[T, U]
|
||||
|
||||
final def <+=[V](v: Initialize[V])(implicit a: Append.Value[T, V]): Setting[T] =
|
||||
macro std.TaskMacro.fakeSettingAppend1Position[T, V]
|
||||
// final def <+=[V](v: Initialize[V])(implicit a: Append.Value[T, V]): Setting[T] =
|
||||
// macro std.TaskMacro.fakeSettingAppend1Position[T, V]
|
||||
|
||||
final def <++=[V](vs: Initialize[V])(implicit a: Append.Values[T, V]): Setting[T] =
|
||||
macro std.TaskMacro.fakeSettingAppendNPosition[T, V]
|
||||
// final def <++=[V](vs: Initialize[V])(implicit a: Append.Values[T, V]): Setting[T] =
|
||||
// macro std.TaskMacro.fakeSettingAppendNPosition[T, V]
|
||||
|
||||
final def -=[U](v: U)(implicit r: Remove.Value[T, U]): Setting[T] =
|
||||
macro std.TaskMacro.settingRemove1Impl[T, U]
|
||||
// final def -=[U](v: U)(implicit r: Remove.Value[T, U]): Setting[T] =
|
||||
// macro std.TaskMacro.settingRemove1Impl[T, U]
|
||||
|
||||
final def --=[U](vs: U)(implicit r: Remove.Values[T, U]): Setting[T] =
|
||||
macro std.TaskMacro.settingRemoveNImpl[T, U]
|
||||
// final def --=[U](vs: U)(implicit r: Remove.Values[T, U]): Setting[T] =
|
||||
// macro std.TaskMacro.settingRemoveNImpl[T, U]
|
||||
|
||||
final def ~=(f: T => T): Setting[T] = macro std.TaskMacro.settingTransformPosition[T]
|
||||
// final def ~=(f: T => T): Setting[T] = macro std.TaskMacro.settingTransformPosition[T]
|
||||
|
||||
final def append1[V](v: Initialize[V], source: SourcePosition)(
|
||||
implicit a: Append.Value[T, V]
|
||||
): Setting[T] = make(v, source)(a.appendValue)
|
||||
final def append1[V](v: Initialize[V], source: SourcePosition)(implicit
|
||||
a: Append.Value[A1, V]
|
||||
): Setting[A1] = make(v, source)(a.appendValue)
|
||||
|
||||
final def appendN[V](vs: Initialize[V], source: SourcePosition)(
|
||||
implicit a: Append.Values[T, V]
|
||||
): Setting[T] = make(vs, source)(a.appendValues)
|
||||
final def appendN[V](vs: Initialize[V], source: SourcePosition)(implicit
|
||||
a: Append.Values[A1, V]
|
||||
): Setting[A1] = make(vs, source)(a.appendValues)
|
||||
|
||||
final def remove1[V](v: Initialize[V], source: SourcePosition)(
|
||||
implicit r: Remove.Value[T, V]
|
||||
): Setting[T] = make(v, source)(r.removeValue)
|
||||
final def removeN[V](vs: Initialize[V], source: SourcePosition)(
|
||||
implicit r: Remove.Values[T, V]
|
||||
): Setting[T] = make(vs, source)(r.removeValues)
|
||||
final def remove1[V](v: Initialize[V], source: SourcePosition)(implicit
|
||||
r: Remove.Value[A1, V]
|
||||
): Setting[A1] = make(v, source)(r.removeValue)
|
||||
final def removeN[V](vs: Initialize[V], source: SourcePosition)(implicit
|
||||
r: Remove.Values[A1, V]
|
||||
): Setting[A1] = make(vs, source)(r.removeValues)
|
||||
|
||||
final def transform(f: T => T, source: SourcePosition): Setting[T] = set(scopedKey(f), source)
|
||||
final def transform(f: A1 => A1, source: SourcePosition): Setting[A1] = set(scopedKey(f), source)
|
||||
|
||||
protected[this] def make[S](other: Initialize[S], source: SourcePosition)(
|
||||
f: (T, S) => T
|
||||
): Setting[T] = set(this.zipWith(other)(f), source)
|
||||
f: (A1, S) => A1
|
||||
): Setting[A1] = set(this.zipWith(other)(f), source)
|
||||
|
||||
final def withRank(rank: Int): SettingKey[T] =
|
||||
final def withRank(rank: Int): SettingKey[A1] =
|
||||
SettingKey(AttributeKey.copyWithRank(key, rank))
|
||||
|
||||
def canEqual(that: Any): Boolean = that.isInstanceOf[SettingKey[_]]
|
||||
}
|
||||
end SettingKey
|
||||
|
||||
/**
|
||||
* Identifies a task. It consists of three parts: the scope, the name, and the type of the value computed by a task associated with this key.
|
||||
|
|
@ -127,67 +127,67 @@ sealed abstract class SettingKey[T]
|
|||
* The name and the type are represented by a value of type `AttributeKey[Task[T]]`.
|
||||
* Instances are constructed using the companion object.
|
||||
*/
|
||||
sealed abstract class TaskKey[T]
|
||||
extends ScopedTaskable[T]
|
||||
with KeyedInitialize[Task[T]]
|
||||
with Scoped.ScopingSetting[TaskKey[T]]
|
||||
with Scoped.DefinableTask[T] {
|
||||
sealed abstract class TaskKey[A1]
|
||||
extends ScopedTaskable[A1]
|
||||
with Def.KeyedInitialize[Task[A1]]
|
||||
with Scoped.ScopingSetting[TaskKey[A1]]
|
||||
with Scoped.DefinableTask[A1]:
|
||||
|
||||
val key: AttributeKey[Task[T]]
|
||||
val key: AttributeKey[Task[A1]]
|
||||
|
||||
override def toString: String = s"TaskKey($scope / $key)"
|
||||
|
||||
def toTask: Initialize[Task[T]] = this
|
||||
def toTask: Initialize[Task[A1]] = this
|
||||
|
||||
def scopedKey: ScopedKey[Task[T]] = ScopedKey(scope, key)
|
||||
def scopedKey: ScopedKey[Task[A1]] = ScopedKey(scope, key)
|
||||
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(scope: Scope): TaskKey[T] =
|
||||
def in(scope: Scope): TaskKey[A1] =
|
||||
Scoped.scopedTask(Scope.replaceThis(this.scope)(scope), this.key)
|
||||
|
||||
def +=[U](v: U)(implicit a: Append.Value[T, U]): Setting[Task[T]] =
|
||||
macro std.TaskMacro.taskAppend1Impl[T, U]
|
||||
// def +=[U](v: U)(implicit a: Append.Value[T, U]): Setting[Task[T]] =
|
||||
// macro std.TaskMacro.taskAppend1Impl[T, U]
|
||||
|
||||
def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[Task[T]] =
|
||||
macro std.TaskMacro.taskAppendNImpl[T, U]
|
||||
// def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[Task[T]] =
|
||||
// macro std.TaskMacro.taskAppendNImpl[T, U]
|
||||
|
||||
def <+=[V](v: Initialize[Task[V]])(implicit a: Append.Value[T, V]): Setting[Task[T]] =
|
||||
macro std.TaskMacro.fakeTaskAppend1Position[T, V]
|
||||
// def <+=[V](v: Initialize[Task[V]])(implicit a: Append.Value[T, V]): Setting[Task[T]] =
|
||||
// macro std.TaskMacro.fakeTaskAppend1Position[T, V]
|
||||
|
||||
def <++=[V](vs: Initialize[Task[V]])(implicit a: Append.Values[T, V]): Setting[Task[T]] =
|
||||
macro std.TaskMacro.fakeTaskAppendNPosition[T, V]
|
||||
// def <++=[V](vs: Initialize[Task[V]])(implicit a: Append.Values[T, V]): Setting[Task[T]] =
|
||||
// macro std.TaskMacro.fakeTaskAppendNPosition[T, V]
|
||||
|
||||
final def -=[U](v: U)(implicit r: Remove.Value[T, U]): Setting[Task[T]] =
|
||||
macro std.TaskMacro.taskRemove1Impl[T, U]
|
||||
// final def -=[U](v: U)(implicit r: Remove.Value[T, U]): Setting[Task[T]] =
|
||||
// macro std.TaskMacro.taskRemove1Impl[T, U]
|
||||
|
||||
final def --=[U](vs: U)(implicit r: Remove.Values[T, U]): Setting[Task[T]] =
|
||||
macro std.TaskMacro.taskRemoveNImpl[T, U]
|
||||
// final def --=[U](vs: U)(implicit r: Remove.Values[T, U]): Setting[Task[T]] =
|
||||
// macro std.TaskMacro.taskRemoveNImpl[T, U]
|
||||
|
||||
def append1[V](v: Initialize[Task[V]], source: SourcePosition)(
|
||||
implicit a: Append.Value[T, V]
|
||||
): Setting[Task[T]] = make(v, source)(a.appendValue)
|
||||
def append1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit
|
||||
a: Append.Value[A1, V]
|
||||
): Setting[Task[A1]] = make(v, source)(a.appendValue)
|
||||
|
||||
def appendN[V](vs: Initialize[Task[V]], source: SourcePosition)(
|
||||
implicit a: Append.Values[T, V]
|
||||
): Setting[Task[T]] = make(vs, source)(a.appendValues)
|
||||
def appendN[V](vs: Initialize[Task[V]], source: SourcePosition)(implicit
|
||||
a: Append.Values[A1, V]
|
||||
): Setting[Task[A1]] = make(vs, source)(a.appendValues)
|
||||
|
||||
final def remove1[V](v: Initialize[Task[V]], source: SourcePosition)(
|
||||
implicit r: Remove.Value[T, V]
|
||||
): Setting[Task[T]] = make(v, source)(r.removeValue)
|
||||
final def remove1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit
|
||||
r: Remove.Value[A1, V]
|
||||
): Setting[Task[A1]] = make(v, source)(r.removeValue)
|
||||
|
||||
final def removeN[V](vs: Initialize[Task[V]], source: SourcePosition)(
|
||||
implicit r: Remove.Values[T, V]
|
||||
): Setting[Task[T]] = make(vs, source)(r.removeValues)
|
||||
final def removeN[V](vs: Initialize[Task[V]], source: SourcePosition)(implicit
|
||||
r: Remove.Values[A1, V]
|
||||
): Setting[Task[A1]] = make(vs, source)(r.removeValues)
|
||||
|
||||
private[this] def make[S](other: Initialize[Task[S]], source: SourcePosition)(
|
||||
f: (T, S) => T
|
||||
): Setting[Task[T]] = set(this.zipWith(other)((a, b) => (a, b) map f.tupled), source)
|
||||
f: (A1, S) => A1
|
||||
): Setting[Task[A1]] = set(this.zipWith(other)((a, b) => (a, b) map f.tupled), source)
|
||||
|
||||
final def withRank(rank: Int): TaskKey[T] =
|
||||
final def withRank(rank: Int): TaskKey[A1] =
|
||||
TaskKey(AttributeKey.copyWithRank(key, rank))
|
||||
|
||||
def canEqual(that: Any): Boolean = that.isInstanceOf[TaskKey[_]]
|
||||
}
|
||||
end TaskKey
|
||||
|
||||
/**
|
||||
* Identifies an input task. An input task parses input and produces a task to run.
|
||||
|
|
@ -196,36 +196,36 @@ sealed abstract class TaskKey[T]
|
|||
* The name and the type are represented by a value of type `AttributeKey[InputTask[T]]`.
|
||||
* Instances are constructed using the companion object.
|
||||
*/
|
||||
sealed trait InputKey[T]
|
||||
sealed trait InputKey[A1]
|
||||
extends Scoped
|
||||
with KeyedInitialize[InputTask[T]]
|
||||
with Scoped.ScopingSetting[InputKey[T]]
|
||||
with Scoped.DefinableSetting[InputTask[T]] {
|
||||
with Def.KeyedInitialize[InputTask[A1]]
|
||||
with Scoped.ScopingSetting[InputKey[A1]]
|
||||
with Scoped.DefinableSetting[InputTask[A1]]:
|
||||
|
||||
val key: AttributeKey[InputTask[T]]
|
||||
val key: AttributeKey[InputTask[A1]]
|
||||
|
||||
override def toString: String = s"InputKey($scope / $key)"
|
||||
|
||||
def scopedKey: ScopedKey[InputTask[T]] = ScopedKey(scope, key)
|
||||
def scopedKey: ScopedKey[InputTask[A1]] = ScopedKey(scope, key)
|
||||
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(scope: Scope): InputKey[T] =
|
||||
def in(scope: Scope): InputKey[A1] =
|
||||
Scoped.scopedInput(Scope.replaceThis(this.scope)(scope), this.key)
|
||||
|
||||
final def :=(v: T): Setting[InputTask[T]] = macro std.TaskMacro.inputTaskAssignMacroImpl[T]
|
||||
final def ~=(f: T => T): Setting[InputTask[T]] = macro std.TaskMacro.itaskTransformPosition[T]
|
||||
// final def :=(v: A1): Setting[InputTask[A1]] = macro std.TaskMacro.inputTaskAssignMacroImpl[A1]
|
||||
// final def ~=(f: A1 => A1): Setting[InputTask[A1]] = macro std.TaskMacro.itaskTransformPosition[A1]
|
||||
|
||||
final def transform(f: T => T, source: SourcePosition): Setting[InputTask[T]] =
|
||||
final def transform(f: A1 => A1, source: SourcePosition): Setting[InputTask[A1]] =
|
||||
set(scopedKey(_ mapTask { _ map f }), source)
|
||||
|
||||
final def withRank(rank: Int): InputKey[T] =
|
||||
final def withRank(rank: Int): InputKey[A1] =
|
||||
InputKey(AttributeKey.copyWithRank(key, rank))
|
||||
|
||||
def canEqual(that: Any): Boolean = that.isInstanceOf[InputKey[_]]
|
||||
}
|
||||
end InputKey
|
||||
|
||||
/** Methods and types related to constructing settings, including keys, scopes, and initializations. */
|
||||
object Scoped {
|
||||
object Scoped:
|
||||
implicit def taskScopedToKey[T](s: TaskKey[T]): ScopedKey[Task[T]] = ScopedKey(s.scope, s.key)
|
||||
|
||||
implicit def inputScopedToKey[T](s: InputKey[T]): ScopedKey[InputTask[T]] =
|
||||
|
|
@ -244,41 +244,41 @@ object Scoped {
|
|||
*
|
||||
* name.in(Compile).:=("hello ugly syntax")
|
||||
* }}}
|
||||
*
|
||||
*/
|
||||
sealed trait ScopingSetting[ResultType] {
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(s: Scope): ResultType
|
||||
sealed trait ScopingSetting[ResultType]:
|
||||
private[sbt] def in(s: Scope): ResultType
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
// def in(s: Scope): ResultType
|
||||
|
||||
@deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(p: Reference): ResultType = in(Select(p), This, This)
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
// def in(p: Reference): ResultType = in(Select(p), This, This)
|
||||
|
||||
@deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(t: Scoped): ResultType = in(This, This, Select(t.key))
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
// def in(t: Scoped): ResultType = in(This, This, Select(t.key))
|
||||
|
||||
@deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(c: ConfigKey): ResultType = in(This, Select(c), This)
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
// def in(c: ConfigKey): ResultType = in(This, Select(c), This)
|
||||
|
||||
@deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(c: ConfigKey, t: Scoped): ResultType = in(This, Select(c), Select(t.key))
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
// def in(c: ConfigKey, t: Scoped): ResultType = in(This, Select(c), Select(t.key))
|
||||
|
||||
@deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(p: Reference, c: ConfigKey): ResultType = in(Select(p), Select(c), This)
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
// def in(p: Reference, c: ConfigKey): ResultType = in(Select(p), Select(c), This)
|
||||
|
||||
@deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(p: Reference, t: Scoped): ResultType = in(Select(p), This, Select(t.key))
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
// def in(p: Reference, t: Scoped): ResultType = in(Select(p), This, Select(t.key))
|
||||
|
||||
@deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(p: Reference, c: ConfigKey, t: Scoped): ResultType =
|
||||
in(Select(p), Select(c), Select(t.key))
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
// def in(p: Reference, c: ConfigKey, t: Scoped): ResultType =
|
||||
// in(Select(p), Select(c), Select(t.key))
|
||||
|
||||
@deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
def in(
|
||||
p: ScopeAxis[Reference],
|
||||
c: ScopeAxis[ConfigKey],
|
||||
t: ScopeAxis[AttributeKey[_]]
|
||||
): ResultType = in(Scope(p, c, t, This))
|
||||
}
|
||||
// @deprecated(Scope.inIsDeprecated, "1.5.0")
|
||||
// def in(
|
||||
// p: ScopeAxis[Reference],
|
||||
// c: ScopeAxis[ConfigKey],
|
||||
// t: ScopeAxis[AttributeKey[_]]
|
||||
// ): ResultType = in(Scope(p, c, t, This))
|
||||
end ScopingSetting
|
||||
|
||||
def scopedSetting[T](s: Scope, k: AttributeKey[T]): SettingKey[T] =
|
||||
new SettingKey[T] { val scope = s; val key = k }
|
||||
|
|
@ -295,10 +295,10 @@ object Scoped {
|
|||
sealed trait DefinableSetting[S] {
|
||||
def scopedKey: ScopedKey[S]
|
||||
|
||||
private[sbt] final def :==(app: S): Setting[S] = macro std.TaskMacro.settingAssignPure[S]
|
||||
// private[sbt] final def :==(app: S): Setting[S] = macro std.TaskMacro.settingAssignPure[S]
|
||||
|
||||
final def <<=(app: Initialize[S]): Setting[S] =
|
||||
macro std.TaskMacro.fakeSettingAssignPosition[S]
|
||||
// final def <<=(app: Initialize[S]): Setting[S] =
|
||||
// macro std.TaskMacro.fakeSettingAssignPosition[S]
|
||||
|
||||
/** Internally used function for setting a value along with the `.sbt` file location where it is defined. */
|
||||
final def set(app: Initialize[S], source: SourcePosition): Setting[S] =
|
||||
|
|
@ -353,46 +353,51 @@ object Scoped {
|
|||
def map[T](f: S => T): Initialize[Task[T]] = init(s => mktask(f(s)))
|
||||
def flatMap[T](f: S => Task[T]): Initialize[Task[T]] = init(f)
|
||||
}
|
||||
sealed trait DefinableTask[S] { self: TaskKey[S] =>
|
||||
|
||||
private[sbt] def :==(app: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignPositionPure[S]
|
||||
sealed trait DefinableTask[A1] { self: TaskKey[A1] =>
|
||||
|
||||
private[sbt] def ::=(app: Task[S]): Setting[Task[S]] =
|
||||
macro std.TaskMacro.taskAssignPositionT[S]
|
||||
// private[sbt] def :==(app: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignPositionPure[S]
|
||||
|
||||
def :=(v: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignMacroImpl[S]
|
||||
def ~=(f: S => S): Setting[Task[S]] = macro std.TaskMacro.taskTransformPosition[S]
|
||||
// private[sbt] def ::=(app: Task[S]): Setting[Task[S]] =
|
||||
// macro std.TaskMacro.taskAssignPositionT[S]
|
||||
|
||||
def <<=(app: Initialize[Task[S]]): Setting[Task[S]] =
|
||||
macro std.TaskMacro.fakeItaskAssignPosition[S]
|
||||
// def :=(v: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignMacroImpl[S]
|
||||
// def ~=(f: S => S): Setting[Task[S]] = macro std.TaskMacro.taskTransformPosition[S]
|
||||
|
||||
def set(app: Initialize[Task[S]], source: SourcePosition): Setting[Task[S]] =
|
||||
// def <<=(app: Initialize[Task[S]]): Setting[Task[S]] =
|
||||
// macro std.TaskMacro.fakeItaskAssignPosition[S]
|
||||
|
||||
def set(app: Initialize[Task[A1]], source: SourcePosition): Setting[Task[A1]] =
|
||||
Def.setting(scopedKey, app, source)
|
||||
|
||||
def transform(f: S => S, source: SourcePosition): Setting[Task[S]] =
|
||||
def transform(f: A1 => A1, source: SourcePosition): Setting[Task[A1]] =
|
||||
set(scopedKey(_ map f), source)
|
||||
|
||||
@deprecated(
|
||||
"No longer needed with new task syntax and SettingKey inheriting from Initialize.",
|
||||
"0.13.2"
|
||||
)
|
||||
def task: SettingKey[Task[S]] = scopedSetting(scope, key)
|
||||
// @deprecated(
|
||||
// "No longer needed with new task syntax and SettingKey inheriting from Initialize.",
|
||||
// "0.13.2"
|
||||
// )
|
||||
// def task: SettingKey[Task[A1]] = scopedSetting(scope, key)
|
||||
|
||||
def toSettingKey: SettingKey[Task[S]] = scopedSetting(scope, key)
|
||||
def toSettingKey: SettingKey[Task[A1]] = scopedSetting(scope, key)
|
||||
|
||||
def get(settings: Settings[Scope]): Option[Task[S]] = settings.get(scope, key)
|
||||
def get(settings: Settings[Scope]): Option[Task[A1]] = settings.get(scope, key)
|
||||
|
||||
def ? : Initialize[Task[Option[S]]] = Def.optional(scopedKey) {
|
||||
case None => mktask { None }; case Some(t) => t map some.fn
|
||||
def ? : Initialize[Task[Option[A1]]] = Def.optional(scopedKey) {
|
||||
case None => mktask { None }
|
||||
case Some(t) => t map some[A1]
|
||||
}
|
||||
|
||||
def ??[T >: S](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))
|
||||
|
||||
def or[T >: S](i: Initialize[Task[T]]): Initialize[Task[T]] =
|
||||
(this.? zipWith i)((x, y) => (x, y) map { case (a, b) => a getOrElse b })
|
||||
// def or[A2 >: A1](i: Initialize[Task[A2]]): Initialize[Task[A2]] =
|
||||
// this.?.zipWith(i) { (toa1: Task[Option[A1]], ta2: Task[A2]) =>
|
||||
// (toa1, ta2).map { case (oa1: Option[A1], a2: A2) => oa1 getOrElse b2 }
|
||||
// }
|
||||
}
|
||||
|
||||
/** Enriches `Initialize[Task[S]]` types.
|
||||
/**
|
||||
* Enriches `Initialize[Task[S]]` types.
|
||||
*
|
||||
* @param i the original `Initialize[Task[S]]` value to enrich
|
||||
* @tparam S the type of the underlying value
|
||||
|
|
@ -407,14 +412,14 @@ object Scoped {
|
|||
def failure: Initialize[Task[Incomplete]] = i(_.failure)
|
||||
def result: Initialize[Task[Result[S]]] = i(_.result)
|
||||
|
||||
def xtriggeredBy[T](tasks: Initialize[Task[T]]*): Initialize[Task[S]] =
|
||||
nonLocal(tasks, Def.triggeredBy)
|
||||
def xtriggeredBy[A1](tasks: Initialize[Task[A1]]*): Initialize[Task[S]] =
|
||||
nonLocal(tasks.toSeq.asInstanceOf[Seq[AnyInitTask]], Def.triggeredBy)
|
||||
|
||||
def triggeredBy[T](tasks: Initialize[Task[T]]*): Initialize[Task[S]] =
|
||||
nonLocal(tasks, Def.triggeredBy)
|
||||
def triggeredBy[A1](tasks: Initialize[Task[A1]]*): Initialize[Task[S]] =
|
||||
nonLocal(tasks.toSeq.asInstanceOf[Seq[AnyInitTask]], Def.triggeredBy)
|
||||
|
||||
def runBefore[T](tasks: Initialize[Task[T]]*): Initialize[Task[S]] =
|
||||
nonLocal(tasks, Def.runBefore)
|
||||
def runBefore[A1](tasks: Initialize[Task[A1]]*): Initialize[Task[S]] =
|
||||
nonLocal(tasks.toSeq.asInstanceOf[Seq[AnyInitTask]], Def.runBefore)
|
||||
|
||||
private[this] def nonLocal(
|
||||
tasks: Seq[AnyInitTask],
|
||||
|
|
@ -423,7 +428,8 @@ object Scoped {
|
|||
Initialize.joinAny[Task](tasks).zipWith(i)((ts, i) => i.copy(info = i.info.set(key, ts)))
|
||||
}
|
||||
|
||||
/** Enriches `Initialize[InputTask[S]]` types.
|
||||
/**
|
||||
* Enriches `Initialize[InputTask[S]]` types.
|
||||
*
|
||||
* @param i the original `Initialize[InputTask[S]]` value to enrich
|
||||
* @tparam S the type of the underlying value
|
||||
|
|
@ -434,13 +440,14 @@ object Scoped {
|
|||
protected def onTask[T](f: Task[S] => Task[T]): Initialize[InputTask[T]] = i(_ mapTask f)
|
||||
|
||||
def dependsOn(tasks: AnyInitTask*): Initialize[InputTask[S]] = {
|
||||
i.zipWith(Initialize.joinAny[Task](tasks))(
|
||||
(thisTask, deps) => thisTask.mapTask(_.dependsOn(deps: _*))
|
||||
i.zipWith(Initialize.joinAny[Task](tasks))((thisTask, deps) =>
|
||||
thisTask.mapTask(_.dependsOn(deps: _*))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Enriches `Initialize[R[S]]` types. Abstracts over the specific task-like type constructor.
|
||||
/**
|
||||
* Enriches `Initialize[R[S]]` types. Abstracts over the specific task-like type constructor.
|
||||
*
|
||||
* @tparam S the type of the underlying vault
|
||||
* @tparam R the task-like type constructor (either Task or InputTask)
|
||||
|
|
@ -487,7 +494,7 @@ object Scoped {
|
|||
def mapFailure[T](f: Incomplete => T): Initialize[R[T]] = onTask(_.result map (f compose failM))
|
||||
}
|
||||
|
||||
type AnyInitTask = Initialize[Task[T]] forSome { type T }
|
||||
type AnyInitTask = Initialize[Task[Any]]
|
||||
|
||||
implicit def richTaskSeq[T](in: Seq[Initialize[Task[T]]]): RichTaskSeq[T] = new RichTaskSeq(in)
|
||||
final class RichTaskSeq[T](keys: Seq[Initialize[Task[T]]]) {
|
||||
|
|
@ -501,8 +508,8 @@ object Scoped {
|
|||
Initialize.joinAny[Task](keys).apply(deps => nop.dependsOn(deps: _*))
|
||||
}
|
||||
|
||||
sealed abstract class RichTaskables[K[L[x]]](final val keys: K[Taskable])(
|
||||
implicit a: AList[K]
|
||||
sealed abstract class RichTaskables[K[L[x]]](final val keys: K[Taskable])(implicit
|
||||
a: AList[K]
|
||||
) {
|
||||
|
||||
type App[T] = Initialize[Task[T]]
|
||||
|
|
@ -513,10 +520,12 @@ object Scoped {
|
|||
/** 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
|
||||
|
||||
private[this] val inputs: K[App] = a.transform(keys, λ[Taskable ~> App](_.toTask))
|
||||
private[this] val inputs: K[App] = a.transform(keys) {
|
||||
[A] => (fa: Taskable[A]) => fa.toTask
|
||||
}
|
||||
|
||||
private[this] def onTasks[T](f: K[Task] => Task[T]): App[T] =
|
||||
Def.app[AList.SplitK[K, Task]#l, Task[T]](inputs)(f)(AList.asplit[K, Task](a))
|
||||
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))
|
||||
|
||||
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)))
|
||||
|
|
@ -529,52 +538,52 @@ object Scoped {
|
|||
// format: off
|
||||
|
||||
type ST[X] = Taskable[X]
|
||||
final class RichTaskable2[A, B](t2: (ST[A], ST[B])) extends RichTaskables[AList.T2K[A, B]#l](t2)(AList.tuple2[A, B]) {
|
||||
final class RichTaskable2[A, B](t2: (ST[A], ST[B])) extends RichTaskables[AList.Tuple2K[A, B]](t2)(AList.tuple2[A, B]) {
|
||||
type Fun[M[_], Ret] = (M[A], M[B]) => Ret
|
||||
def identityMap = map(mkTuple2)
|
||||
protected def convert[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.T3K[A, B, C]#l](t3)(AList.tuple3[A, B, C]) {
|
||||
final class RichTaskable3[A, B, C](t3: (ST[A], ST[B], ST[C])) extends RichTaskables[AList.Tuple3K[A, B, C]](t3)(AList.tuple3[A, B, C]) {
|
||||
type Fun[M[_], Ret] = (M[A], M[B], M[C]) => Ret
|
||||
def identityMap = map(mkTuple3)
|
||||
protected def convert[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.T4K[A, B, C, D]#l](t4)(AList.tuple4[A, B, C, D]) {
|
||||
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)(AList.tuple4[A, B, C, D]) {
|
||||
type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D]) => Ret
|
||||
def identityMap = map(mkTuple4)
|
||||
protected def convert[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.T5K[A, B, C, D, E]#l](t5)(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[AList.Tuple5K[A, B, C, D, E]](t5)(AList.tuple5[A, B, C, D, E]) {
|
||||
type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E]) => Ret
|
||||
def identityMap = map(mkTuple5)
|
||||
protected def convert[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.T6K[A, B, C, D, E, F]#l](t6)(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[AList.Tuple6K[A, B, C, D, E, F]](t6)(AList.tuple6[A, B, C, D, E, F]) {
|
||||
type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F]) => Ret
|
||||
def identityMap = map(mkTuple6)
|
||||
protected def convert[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.T7K[A, B, C, D, E, F, G]#l](t7)(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[AList.Tuple7K[A, B, C, D, E, F, G]](t7)(AList.tuple7[A, B, C, D, E, F, G]) {
|
||||
type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G]) => Ret
|
||||
def identityMap = map(mkTuple7)
|
||||
protected def convert[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.T8K[A, B, C, D, E, F, G, H]#l](t8)(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[AList.Tuple8K[A, B, C, D, E, F, G, H]](t8)(AList.tuple8[A, B, C, D, E, F, G, H]) {
|
||||
type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H]) => Ret
|
||||
def identityMap = map(mkTuple8)
|
||||
protected def convert[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.T9K[A, B, C, D, E, F, G, H, I]#l](t9)(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[AList.Tuple9K[A, B, C, D, E, F, G, H, I]](t9)(AList.tuple9[A, B, C, D, E, F, G, H, I]) {
|
||||
type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I]) => Ret
|
||||
def identityMap = map(mkTuple9)
|
||||
protected def convert[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.T10K[A, B, C, D, E, F, G, H, I, J]#l](t10)(AList.tuple10[A, B, C, D, E, F, G, H, I, J]) {
|
||||
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)(AList.tuple10[A, B, C, D, E, F, G, H, I, J]) {
|
||||
type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J]) => Ret
|
||||
def identityMap = map(mkTuple10)
|
||||
protected def convert[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.T11K[A, B, C, D, E, F, G, H, I, J, K]#l](t11)(AList.tuple11[A, B, C, D, E, F, G, H, I, J, K]) {
|
||||
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)(AList.tuple11[A, B, C, D, E, F, G, H, I, J, K]) {
|
||||
type Fun[M[_], Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K]) => Ret
|
||||
def identityMap = map(mkTuple11)
|
||||
protected def convert[M[_], R](z: Fun[M, R]) = z.tupled
|
||||
|
|
@ -595,54 +604,64 @@ object Scoped {
|
|||
def mkTuple14[A, B, C, D, E, F, G, H, I, J, K, L, N, O] = (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) => (a, b, c, d, e, f, g, h, i, j, k, l, n, o)
|
||||
def mkTuple15[A, B, C, D, E, F, G, H, I, J, K, L, N, O, P] = (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L, n: N, o: O, p: P) => (a, b, c, d, e, f, g, h, i, j, k, l, n, o, p)
|
||||
|
||||
final class Apply2[A, B](t2: (Initialize[A], Initialize[B])) {
|
||||
def apply[T](z: (A, B) => T) = Def.app[AList.T2K[A, B]#l, T](t2)(z.tupled)(AList.tuple2[A, 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 identity = apply(mkTuple2)
|
||||
}
|
||||
final class Apply3[A, B, C](t3: (Initialize[A], Initialize[B], Initialize[C])) {
|
||||
def apply[T](z: (A, B, C) => T) = Def.app[AList.T3K[A, B, C]#l, T](t3)(z.tupled)(AList.tuple3[A, B, C])
|
||||
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 identity = apply(mkTuple3)
|
||||
}
|
||||
final class Apply4[A, B, C, D](t4: (Initialize[A], Initialize[B], Initialize[C], Initialize[D])) {
|
||||
def apply[T](z: (A, B, C, D) => T) = Def.app[AList.T4K[A, B, C, D]#l, T](t4)(z.tupled)(AList.tuple4[A, B, C, D])
|
||||
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 identity = apply(mkTuple4)
|
||||
}
|
||||
final class Apply5[A, B, C, D, E](t5: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E])) {
|
||||
def apply[T](z: (A, B, C, D, E) => T) = Def.app[AList.T5K[A, B, C, D, E]#l, T](t5)(z.tupled)(AList.tuple5[A, B, C, D, E])
|
||||
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 identity = apply(mkTuple5)
|
||||
}
|
||||
final class Apply6[A, B, C, D, E, F](t6: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F])) {
|
||||
def apply[T](z: (A, B, C, D, E, F) => T) = Def.app[AList.T6K[A, B, C, D, E, F]#l, T](t6)(z.tupled)(AList.tuple6[A, B, C, D, E, F])
|
||||
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 identity = apply(mkTuple6)
|
||||
}
|
||||
final class Apply7[A, B, C, D, E, F, G](t7: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G])) {
|
||||
def apply[T](z: (A, B, C, D, E, F, G) => T) = Def.app[AList.T7K[A, B, C, D, E, F, G]#l, T](t7)(z.tupled)(AList.tuple7[A, B, C, D, E, F, G])
|
||||
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 identity = apply(mkTuple7)
|
||||
}
|
||||
final class Apply8[A, B, C, D, E, F, G, H](t8: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H])) {
|
||||
def apply[T](z: (A, B, C, D, E, F, G, H) => T) = Def.app[AList.T8K[A, B, C, D, E, F, G, H]#l, T](t8)(z.tupled)(AList.tuple8[A, B, C, D, E, F, G, H])
|
||||
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 identity = apply(mkTuple8)
|
||||
}
|
||||
final class Apply9[A, B, C, D, E, F, G, H, I](t9: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I])) {
|
||||
def apply[T](z: (A, B, C, D, E, F, G, H, I) => T) = Def.app[AList.T9K[A, B, C, D, E, F, G, H, I]#l, T](t9)(z.tupled)(AList.tuple9[A, B, C, D, E, F, G, H, I])
|
||||
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 identity = apply(mkTuple9)
|
||||
}
|
||||
final class Apply10[A, B, C, D, E, F, G, H, I, J](t10: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J])) {
|
||||
def apply[T](z: (A, B, C, D, E, F, G, H, I, J) => T) = Def.app[AList.T10K[A, B, C, D, E, F, G, H, I, J]#l, T](t10)(z.tupled)(AList.tuple10[A, B, C, D, E, F, G, H, I, J])
|
||||
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 identity = apply(mkTuple10)
|
||||
}
|
||||
final class Apply11[A, B, C, D, E, F, G, H, I, J, K](t11: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K])) {
|
||||
def apply[T](z: (A, B, C, D, E, F, G, H, I, J, K) => T) = Def.app[AList.T11K[A, B, C, D, E, F, G, H, I, J, K]#l, T](t11)(z.tupled)(AList.tuple11[A, B, C, D, E, F, G, H, I, J, K])
|
||||
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 identity = apply(mkTuple11)
|
||||
}
|
||||
end Apply11
|
||||
|
||||
// format: on
|
||||
|
||||
private[sbt] def extendScoped(s1: Scoped, ss: Seq[Scoped]): Seq[AttributeKey[_]] =
|
||||
s1.key +: ss.map(_.key)
|
||||
}
|
||||
end Scoped
|
||||
|
||||
/** The sbt 0.10 style DSL was deprecated in 0.13.13, favouring the use of the '.value' macro.
|
||||
/**
|
||||
* The sbt 0.10 style DSL was deprecated in 0.13.13, favouring the use of the '.value' macro.
|
||||
*
|
||||
* See https://www.scala-sbt.org/1.x/docs/Migrating-from-sbt-013x.html#Migrating+from+sbt+0.12+style for how to migrate.
|
||||
*/
|
||||
|
|
@ -682,93 +701,98 @@ object TupleSyntax extends TupleSyntax
|
|||
|
||||
import Scoped.extendScoped
|
||||
|
||||
/** Constructs InputKeys, which are associated with input tasks to define a setting.*/
|
||||
object InputKey {
|
||||
def apply[T: Manifest](
|
||||
/** Constructs InputKeys, which are associated with input tasks to define a setting. */
|
||||
object InputKey:
|
||||
def apply[A1: Manifest](
|
||||
label: String,
|
||||
description: String = "",
|
||||
rank: Int = KeyRanks.DefaultInputRank
|
||||
): InputKey[T] =
|
||||
apply(AttributeKey[InputTask[T]](label, description, rank))
|
||||
): InputKey[A1] =
|
||||
apply(AttributeKey[InputTask[A1]](label, description, rank))
|
||||
|
||||
def apply[T: Manifest](
|
||||
def apply[A1: Manifest](
|
||||
label: String,
|
||||
description: String,
|
||||
extend1: Scoped,
|
||||
extendN: Scoped*
|
||||
): InputKey[T] = apply(label, description, KeyRanks.DefaultInputRank, extend1, extendN: _*)
|
||||
): InputKey[A1] = apply(label, description, KeyRanks.DefaultInputRank, extend1, extendN: _*)
|
||||
|
||||
def apply[T: Manifest](
|
||||
def apply[A1: Manifest](
|
||||
label: String,
|
||||
description: String,
|
||||
rank: Int,
|
||||
extend1: Scoped,
|
||||
extendN: Scoped*
|
||||
): InputKey[T] =
|
||||
apply(AttributeKey[InputTask[T]](label, description, extendScoped(extend1, extendN), rank))
|
||||
): InputKey[A1] =
|
||||
apply(AttributeKey[InputTask[A1]](label, description, extendScoped(extend1, extendN), rank))
|
||||
|
||||
def apply[T](akey: AttributeKey[InputTask[T]]): InputKey[T] =
|
||||
def apply[A1](akey: AttributeKey[InputTask[A1]]): InputKey[A1] =
|
||||
Scoped.scopedInput(Scope.ThisScope, akey)
|
||||
}
|
||||
|
||||
/** Constructs TaskKeys, which are associated with tasks to define a setting.*/
|
||||
object TaskKey {
|
||||
def apply[T: Manifest](
|
||||
end InputKey
|
||||
|
||||
/** Constructs TaskKeys, which are associated with tasks to define a setting. */
|
||||
object TaskKey:
|
||||
def apply[A1: Manifest](
|
||||
label: String,
|
||||
description: String = "",
|
||||
rank: Int = KeyRanks.DefaultTaskRank
|
||||
): TaskKey[T] =
|
||||
apply(AttributeKey[Task[T]](label, description, rank))
|
||||
): TaskKey[A1] =
|
||||
apply(AttributeKey[Task[A1]](label, description, rank))
|
||||
|
||||
def apply[T: Manifest](
|
||||
def apply[A1: Manifest](
|
||||
label: String,
|
||||
description: String,
|
||||
extend1: Scoped,
|
||||
extendN: Scoped*
|
||||
): TaskKey[T] =
|
||||
apply(AttributeKey[Task[T]](label, description, extendScoped(extend1, extendN)))
|
||||
): TaskKey[A1] =
|
||||
apply(AttributeKey[Task[A1]](label, description, extendScoped(extend1, extendN)))
|
||||
|
||||
def apply[T: Manifest](
|
||||
def apply[A1: Manifest](
|
||||
label: String,
|
||||
description: String,
|
||||
rank: Int,
|
||||
extend1: Scoped,
|
||||
extendN: Scoped*
|
||||
): TaskKey[T] =
|
||||
apply(AttributeKey[Task[T]](label, description, extendScoped(extend1, extendN), rank))
|
||||
): TaskKey[A1] =
|
||||
apply(AttributeKey[Task[A1]](label, description, extendScoped(extend1, extendN), rank))
|
||||
|
||||
def apply[T](akey: AttributeKey[Task[T]]): TaskKey[T] = Scoped.scopedTask(Scope.ThisScope, akey)
|
||||
def apply[A1](akey: AttributeKey[Task[A1]]): TaskKey[A1] =
|
||||
Scoped.scopedTask(Scope.ThisScope, akey)
|
||||
|
||||
def local[T: Manifest]: TaskKey[T] = apply[T](AttributeKey.local[Task[T]])
|
||||
}
|
||||
def local[A1: Manifest]: TaskKey[A1] = apply[A1](AttributeKey.local[Task[A1]])
|
||||
|
||||
/** Constructs SettingKeys, which are associated with a value to define a basic setting.*/
|
||||
object SettingKey {
|
||||
def apply[T: Manifest: OptJsonWriter](
|
||||
end TaskKey
|
||||
|
||||
/** Constructs SettingKeys, which are associated with a value to define a basic setting. */
|
||||
object SettingKey:
|
||||
def apply[A1: Manifest: OptJsonWriter](
|
||||
label: String,
|
||||
description: String = "",
|
||||
rank: Int = KeyRanks.DefaultSettingRank
|
||||
): SettingKey[T] =
|
||||
apply(AttributeKey[T](label, description, rank))
|
||||
): SettingKey[A1] =
|
||||
apply(AttributeKey[A1](label, description, rank))
|
||||
|
||||
def apply[T: Manifest: OptJsonWriter](
|
||||
def apply[A1: Manifest: OptJsonWriter](
|
||||
label: String,
|
||||
description: String,
|
||||
extend1: Scoped,
|
||||
extendN: Scoped*
|
||||
): SettingKey[T] =
|
||||
apply(AttributeKey[T](label, description, extendScoped(extend1, extendN)))
|
||||
): SettingKey[A1] =
|
||||
apply(AttributeKey[A1](label, description, extendScoped(extend1, extendN)))
|
||||
|
||||
def apply[T: Manifest: OptJsonWriter](
|
||||
def apply[A1: Manifest: OptJsonWriter](
|
||||
label: String,
|
||||
description: String,
|
||||
rank: Int,
|
||||
extend1: Scoped,
|
||||
extendN: Scoped*
|
||||
): SettingKey[T] =
|
||||
apply(AttributeKey[T](label, description, extendScoped(extend1, extendN), rank))
|
||||
): SettingKey[A1] =
|
||||
apply(AttributeKey[A1](label, description, extendScoped(extend1, extendN), rank))
|
||||
|
||||
def apply[T](akey: AttributeKey[T]): SettingKey[T] = Scoped.scopedSetting(Scope.ThisScope, akey)
|
||||
def apply[A1](akey: AttributeKey[A1]): SettingKey[A1] =
|
||||
Scoped.scopedSetting(Scope.ThisScope, akey)
|
||||
|
||||
def local[T: Manifest: OptJsonWriter]: SettingKey[T] = apply[T](AttributeKey.local[T])
|
||||
}
|
||||
def local[A1: Manifest: OptJsonWriter]: SettingKey[A1] = apply[A1](AttributeKey.local[A1])
|
||||
|
||||
end SettingKey
|
||||
|
|
|
|||
|
|
@ -8,81 +8,103 @@
|
|||
package sbt
|
||||
package std
|
||||
|
||||
import scala.reflect.macros._
|
||||
|
||||
import sbt.internal.util.appmacro.{ Convert, ContextUtil }
|
||||
import sbt.internal.util.complete.Parser
|
||||
import sbt.internal.util.appmacro.{ Convert, Converted }
|
||||
import Def.Initialize
|
||||
import scala.quoted.*
|
||||
|
||||
object InputInitConvert extends Convert {
|
||||
def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] =
|
||||
nme match {
|
||||
case InputWrapper.WrapInitName => Converted.Success[c.type](in)
|
||||
case InputWrapper.WrapInitTaskName => Converted.Failure[c.type](in.pos, initTaskErrorMessage)
|
||||
case _ => Converted.NotApplicable[c.type]
|
||||
}
|
||||
class InputInitConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
||||
extends Convert[C](qctx)
|
||||
with ContextUtil[C](qctx):
|
||||
import qctx.reflect.*
|
||||
|
||||
override def convert[A: Type](nme: String, in: Term): Converted =
|
||||
nme match
|
||||
case InputWrapper.WrapInitName => Converted.success(in)
|
||||
case InputWrapper.WrapInitTaskName => Converted.Failure(in.pos, initTaskErrorMessage)
|
||||
case _ => Converted.NotApplicable()
|
||||
|
||||
private def initTaskErrorMessage = "Internal sbt error: initialize+task wrapper not split"
|
||||
}
|
||||
end InputInitConvert
|
||||
|
||||
/** Converts an input `Tree` of type `Parser[T]` or `State => Parser[T]` into a `Tree` of type `State => Parser[T]`.*/
|
||||
object ParserConvert extends Convert {
|
||||
def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] =
|
||||
nme match {
|
||||
case ParserInput.WrapName => Converted.Success[c.type](in)
|
||||
case ParserInput.WrapInitName => Converted.Failure[c.type](in.pos, initParserErrorMessage)
|
||||
case _ => Converted.NotApplicable[c.type]
|
||||
}
|
||||
/** Converts an input `Term` of type `Parser[A]` or `State => Parser[A]` into a `Term` of type `State => Parser[A]`. */
|
||||
class ParserConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
||||
extends Convert[C](qctx)
|
||||
with ContextUtil[C](qctx):
|
||||
import qctx.reflect.*
|
||||
|
||||
override def convert[A: Type](nme: String, in: Term): Converted =
|
||||
nme match
|
||||
case ParserInput.WrapName => Converted.success(in)
|
||||
case ParserInput.WrapInitName => Converted.Failure(in.pos, initParserErrorMessage)
|
||||
case _ => Converted.NotApplicable()
|
||||
|
||||
private def initParserErrorMessage = "Internal sbt error: initialize+parser wrapper not split"
|
||||
}
|
||||
end ParserConvert
|
||||
|
||||
/** Convert instance for plain `Task`s not within the settings system. */
|
||||
object TaskConvert extends Convert {
|
||||
def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] =
|
||||
if (nme == InputWrapper.WrapTaskName) Converted.Success[c.type](in)
|
||||
else Converted.NotApplicable[c.type]
|
||||
}
|
||||
|
||||
/** Converts an input `Tree` of type `Initialize[T]`, `Initialize[Task[T]]`, or `Task[T]` into a `Tree` of type `Initialize[Task[T]]`.*/
|
||||
object FullConvert extends Convert {
|
||||
def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] =
|
||||
nme match {
|
||||
case InputWrapper.WrapInitTaskName => Converted.Success[c.type](in)
|
||||
case InputWrapper.WrapPreviousName => Converted.Success[c.type](in)
|
||||
case InputWrapper.WrapInitName => wrapInit[T](c)(in)
|
||||
case InputWrapper.WrapTaskName => wrapTask[T](c)(in)
|
||||
case _ => Converted.NotApplicable[c.type]
|
||||
}
|
||||
|
||||
private def wrapInit[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree): Converted[c.type] = {
|
||||
val i = c.Expr[Initialize[T]](tree)
|
||||
val t = c.universe.reify(Def.toITask(i.splice)).tree
|
||||
Converted.Success[c.type](t)
|
||||
}
|
||||
|
||||
private def wrapTask[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree): Converted[c.type] = {
|
||||
val i = c.Expr[Task[T]](tree)
|
||||
val t = c.universe.reify(Def.valueStrict[Task[T]](i.splice)).tree
|
||||
Converted.Success[c.type](t)
|
||||
}
|
||||
}
|
||||
class TaskConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
||||
extends Convert[C](qctx)
|
||||
with ContextUtil[C](qctx):
|
||||
import qctx.reflect.*
|
||||
override def convert[A: Type](nme: String, in: Term): Converted =
|
||||
if nme == InputWrapper.WrapTaskName then Converted.success(in)
|
||||
else Converted.NotApplicable()
|
||||
end TaskConvert
|
||||
|
||||
/**
|
||||
* Converts an input `Tree` of type `State => Parser[T]` or `Initialize[State => Parser[T]]`
|
||||
* into a `Tree` of type `Initialize[State => Parser[T]]`.
|
||||
* Converts an input `Term` of type `Initialize[A]`, `Initialize[Task[A]]`, or `Task[A]` into
|
||||
* a `Term` of type `Initialize[Task[A]]`.
|
||||
*/
|
||||
object InitParserConvert extends Convert {
|
||||
def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] =
|
||||
nme match {
|
||||
case ParserInput.WrapName => wrap[T](c)(in)
|
||||
case ParserInput.WrapInitName => Converted.Success[c.type](in)
|
||||
case _ => Converted.NotApplicable[c.type]
|
||||
}
|
||||
class FullConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
||||
extends Convert[C](qctx)
|
||||
with ContextUtil[C](qctx):
|
||||
import qctx.reflect.*
|
||||
|
||||
private def wrap[T: c.WeakTypeTag](c: blackbox.Context)(tree: c.Tree): Converted[c.type] = {
|
||||
val e = c.Expr[State => Parser[T]](tree)
|
||||
val t = c.universe.reify { Def.valueStrict[State => Parser[T]](e.splice) }
|
||||
Converted.Success[c.type](t.tree)
|
||||
}
|
||||
}
|
||||
override def convert[A: Type](nme: String, in: Term): Converted =
|
||||
nme match
|
||||
case InputWrapper.WrapInitTaskName => Converted.success(in)
|
||||
case InputWrapper.WrapPreviousName => Converted.success(in)
|
||||
case InputWrapper.WrapInitName => wrapInit[A](in)
|
||||
case InputWrapper.WrapTaskName => wrapTask[A](in)
|
||||
case _ => Converted.NotApplicable()
|
||||
|
||||
private def wrapInit[A: Type](tree: Term): Converted =
|
||||
val i = tree.asExprOf[Initialize[A]]
|
||||
val t = '{
|
||||
Def.toITask($i)
|
||||
}
|
||||
Converted.success(t.asTerm)
|
||||
|
||||
private def wrapTask[A: Type](tree: Term): Converted =
|
||||
val i = tree.asExprOf[Task[A]]
|
||||
val t = '{
|
||||
Def.valueStrict[Task[A]]($i)
|
||||
}
|
||||
Converted.success(t.asTerm)
|
||||
|
||||
end FullConvert
|
||||
|
||||
/**
|
||||
* Converts an input `Term` of type `State => Parser[A]` or `Initialize[State => Parser[A]]`
|
||||
* into a `Term` of type `Initialize[State => Parser[A]]`.
|
||||
*/
|
||||
class InitParserConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
||||
extends Convert[C](qctx)
|
||||
with ContextUtil[C](qctx):
|
||||
import qctx.reflect.*
|
||||
|
||||
override def convert[A: Type](nme: String, in: Term): Converted =
|
||||
nme match
|
||||
case ParserInput.WrapName => wrap[A](in)
|
||||
case ParserInput.WrapInitName => Converted.success(in)
|
||||
case _ => Converted.NotApplicable()
|
||||
|
||||
private def wrap[A: Type](tree: Term): Converted =
|
||||
val e = tree.asExprOf[State => Parser[A]]
|
||||
val t = '{
|
||||
Def.valueStrict[State => Parser[A]]($e)
|
||||
}
|
||||
Converted.success(t.asTerm)
|
||||
|
||||
end InitParserConvert
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ import sbt.internal.util.appmacro.ContextUtil
|
|||
import sbt.internal.util.complete.Parser
|
||||
|
||||
/** Implementation detail. The wrap methods temporarily hold inputs (as a Tree, at compile time) until a task or setting macro processes it. */
|
||||
object InputWrapper {
|
||||
object InputWrapper:
|
||||
/* The names of the wrapper methods should be obscure.
|
||||
* Wrapper checking is based solely on this name, so it must not conflict with a user method name.
|
||||
* The user should never see this method because it is compile-time only and only used internally by the task macro system.*/
|
||||
* Wrapper checking is based solely on this name, so it must not conflict with a user method name.
|
||||
* The user should never see this method because it is compile-time only and only used internally by the task macro system.*/
|
||||
|
||||
private[std] final val WrapTaskName = "wrapTask_\u2603\u2603"
|
||||
private[std] final val WrapInitName = "wrapInit_\u2603\u2603"
|
||||
|
|
@ -62,7 +62,7 @@ object InputWrapper {
|
|||
|
||||
private[this] def implDetailError =
|
||||
sys.error("This method is an implementation detail and should not be referenced.")
|
||||
|
||||
/*
|
||||
private[std] def wrapTask[T: c.WeakTypeTag](c: blackbox.Context)(
|
||||
ts: c.Expr[Any],
|
||||
pos: c.Position
|
||||
|
|
@ -100,11 +100,11 @@ object InputWrapper {
|
|||
wrapImpl[Option[T], InputWrapper.type](c, InputWrapper, WrapPreviousName)(ts, pos)
|
||||
|
||||
/**
|
||||
* Wraps an arbitrary Tree in a call to the `<s>.<wrapName>` method of this module for later processing by an enclosing macro.
|
||||
* The resulting Tree is the manually constructed version of:
|
||||
*
|
||||
* `c.universe.reify { <s>.<wrapName>[T](ts.splice) }`
|
||||
*/
|
||||
* Wraps an arbitrary Tree in a call to the `<s>.<wrapName>` method of this module for later processing by an enclosing macro.
|
||||
* The resulting Tree is the manually constructed version of:
|
||||
*
|
||||
* `c.universe.reify { <s>.<wrapName>[T](ts.splice) }`
|
||||
*/
|
||||
def wrapImpl[T: c.WeakTypeTag, S <: AnyRef with Singleton](
|
||||
c: blackbox.Context,
|
||||
s: S,
|
||||
|
|
@ -117,7 +117,9 @@ object InputWrapper {
|
|||
val tpe = c.weakTypeOf[T]
|
||||
val nme = TermName(wrapName).encodedName
|
||||
val sel = Select(Ident(iw), nme)
|
||||
sel.setPos(pos) // need to set the position on Select, because that is where the compileTimeOnly check looks
|
||||
sel.setPos(
|
||||
pos
|
||||
) // need to set the position on Select, because that is where the compileTimeOnly check looks
|
||||
val tree = ApplyTree(TypeApply(sel, TypeTree(tpe) :: Nil), ts.tree :: Nil)
|
||||
tree.setPos(ts.tree.pos)
|
||||
// JZ: I'm not sure why we need to do this. Presumably a caller is wrapping this tree in a
|
||||
|
|
@ -166,7 +168,7 @@ object InputWrapper {
|
|||
unexpectedType(c)(pos, tpe)
|
||||
}
|
||||
|
||||
/** Translates <task: TaskKey[T]>.previous(format) to Previous.runtime(<task>)(format).value*/
|
||||
/** Translates <task: TaskKey[T]>.previous(format) to Previous.runtime(<task>)(format).value */
|
||||
def previousMacroImpl[T: c.WeakTypeTag](
|
||||
c: blackbox.Context
|
||||
)(format: c.Expr[sjsonnew.JsonFormat[T]]): c.Expr[Option[T]] = {
|
||||
|
|
@ -177,16 +179,17 @@ object InputWrapper {
|
|||
val tsTyped = c.Expr[TaskKey[T]](t)
|
||||
val newTree = c.universe.reify { Previous.runtime[T](tsTyped.splice)(format.splice) }
|
||||
wrapPrevious[T](c)(newTree, a.pos)
|
||||
} else
|
||||
unexpectedType(c)(a.pos, t.tpe)
|
||||
} else unexpectedType(c)(a.pos, t.tpe)
|
||||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
}
|
||||
|
||||
private def unexpectedType(c: blackbox.Context)(pos: c.Position, tpe: c.Type) =
|
||||
c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.widen}")
|
||||
}
|
||||
*/
|
||||
end InputWrapper
|
||||
|
||||
/*
|
||||
sealed abstract class MacroTaskValue[T] {
|
||||
@compileTimeOnly(
|
||||
"`taskValue` can only be used within a setting macro, such as :=, +=, ++=, or Def.setting."
|
||||
|
|
@ -222,18 +225,19 @@ sealed abstract class ParserInputTask[T] {
|
|||
def parsed: Task[T] = macro ParserInput.parsedInputMacroImpl[T]
|
||||
}
|
||||
sealed abstract class MacroPrevious[T] {
|
||||
@compileTimeOnly(
|
||||
"`previous` can only be used within a task macro, such as :=, +=, ++=, or Def.task."
|
||||
)
|
||||
def previous(implicit format: sjsonnew.JsonFormat[T]): Option[T] =
|
||||
macro InputWrapper.previousMacroImpl[T]
|
||||
// @compileTimeOnly(
|
||||
// "`previous` can only be used within a task macro, such as :=, +=, ++=, or Def.task."
|
||||
// )
|
||||
// def previous(implicit format: sjsonnew.JsonFormat[T]): Option[T] =
|
||||
// macro InputWrapper.previousMacroImpl[T]
|
||||
}
|
||||
*/
|
||||
|
||||
/** Implementation detail. The wrap method temporarily holds the input parser (as a Tree, at compile time) until the input task macro processes it. */
|
||||
object ParserInput {
|
||||
object ParserInput:
|
||||
/* The name of the wrapper method should be obscure.
|
||||
* Wrapper checking is based solely on this name, so it must not conflict with a user method name.
|
||||
* The user should never see this method because it is compile-time only and only used internally by the task macros.*/
|
||||
* Wrapper checking is based solely on this name, so it must not conflict with a user method name.
|
||||
* The user should never see this method because it is compile-time only and only used internally by the task macros.*/
|
||||
private[std] val WrapName = "parser_\u2603\u2603"
|
||||
private[std] val WrapInitName = "initParser_\u2603\u2603"
|
||||
|
||||
|
|
@ -248,7 +252,7 @@ object ParserInput {
|
|||
)
|
||||
def `initParser_\u2603\u2603`[T](@deprecated("unused", "") i: Any): T =
|
||||
sys.error("This method is an implementation detail and should not be referenced.")
|
||||
|
||||
/*
|
||||
private[std] def wrap[T: c.WeakTypeTag](
|
||||
c: blackbox.Context
|
||||
)(ts: c.Expr[Any], pos: c.Position): c.Expr[T] =
|
||||
|
|
@ -287,7 +291,7 @@ object ParserInput {
|
|||
wrapInit[Task[T]](c)(c.universe.reify { Def.toIParser(e.splice) }, pos)
|
||||
}
|
||||
|
||||
/** Implements `Parser[T].parsed` by wrapping the Parser with the ParserInput wrapper.*/
|
||||
/** Implements `Parser[T].parsed` by wrapping the Parser with the ParserInput wrapper. */
|
||||
def parsedMacroImpl[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[T] =
|
||||
ContextUtil.selectMacroImpl[T](c) { (p, pos) =>
|
||||
p.tree.tpe match {
|
||||
|
|
@ -296,7 +300,7 @@ object ParserInput {
|
|||
case tpe if tpe <:< c.weakTypeOf[Initialize[Parser[T]]] =>
|
||||
wrapInitParser[T](c)(p.tree, pos)
|
||||
case tpe if tpe <:< c.weakTypeOf[Initialize[State => Parser[T]]] => wrapInit[T](c)(p, pos)
|
||||
case tpe => unexpectedType(c)(pos, tpe, "parsedMacroImpl")
|
||||
case tpe => unexpectedType(c)(pos, tpe, "parsedMacroImpl")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -315,4 +319,6 @@ object ParserInput {
|
|||
|
||||
private def unexpectedType(c: blackbox.Context)(pos: c.Position, tpe: c.Type, label: String) =
|
||||
c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.dealias} in $label.")
|
||||
}
|
||||
*/
|
||||
|
||||
end ParserInput
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2011 - 2018, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt
|
||||
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.complete.{ DefaultParsers, Parser }
|
||||
|
||||
object InitializeInstance:
|
||||
given initializeMonad: Monad[Initialize] with
|
||||
type F[x] = Initialize[x]
|
||||
|
||||
override def pure[A1](a: () => A1): Initialize[A1] = Def.pure(a)
|
||||
override def map[A1, A2](in: Initialize[A1])(f: A1 => A2): Initialize[A2] = Def.map(in)(f)
|
||||
override def ap[A1, A2](ff: Initialize[A1 => A2])(fa: Initialize[A1]): Initialize[A2] =
|
||||
Def.ap[A1, A2](ff)(fa)
|
||||
override def flatMap[A1, A2](fa: Initialize[A1])(f: A1 => Initialize[A2]) =
|
||||
Def.flatMap[A1, A2](fa)(f)
|
||||
end InitializeInstance
|
||||
|
||||
private[std] object ComposeInstance:
|
||||
import InitializeInstance.initializeMonad
|
||||
val InitInstance = summon[Applicative[Initialize]]
|
||||
val F1F2: Applicative[Compose[Initialize, Task]] = summon[Applicative[Compose[Initialize, Task]]]
|
||||
end ComposeInstance
|
||||
|
||||
object ParserInstance:
|
||||
// import sbt.internal.util.Classes.Applicative
|
||||
// private[this] implicit val parserApplicative: Applicative[M] = new Applicative[M] {
|
||||
// def apply[S, T](f: M[S => T], v: M[S]): M[A1] = s => (f(s) ~ v(s)) map { case (a, b) => a(b) }
|
||||
// def pure[S](s: => S) = const(Parser.success(s))
|
||||
// def map[S, T](f: S => T, v: M[S]) = s => v(s).map(f)
|
||||
// }
|
||||
|
||||
given Applicative[[a] =>> State => Parser[a]] with
|
||||
type F[x] = State => Parser[x]
|
||||
override def pure[A1](a: () => A1): State => Parser[A1] = const(DefaultParsers.success(a()))
|
||||
override def ap[A1, A2](ff: F[A1 => A2])(fa: F[A1]): F[A2] =
|
||||
(s: State) => (ff(s) ~ fa(s)).map { case (f, a) => f(a) }
|
||||
override def map[A1, A2](fa: F[A1])(f: A1 => A2) =
|
||||
(s: State) => fa(s).map(f)
|
||||
end ParserInstance
|
||||
|
||||
/** Composes the Task and Initialize Instances to provide an Instance for [A1] Initialize[Task[A1]]. */
|
||||
object FullInstance:
|
||||
type SS = sbt.internal.util.Settings[Scope]
|
||||
val settingsData = TaskKey[SS](
|
||||
"settings-data",
|
||||
"Provides access to the project data for the build.",
|
||||
KeyRanks.DTask
|
||||
)
|
||||
|
||||
given Monad[Initialize] = InitializeInstance.initializeMonad
|
||||
val F1F2: Applicative[Compose[Initialize, Task]] = ComposeInstance.F1F2
|
||||
given Monad[Compose[Initialize, Task]] with
|
||||
type F[x] = Initialize[Task[x]]
|
||||
override def pure[A1](x: () => A1): Initialize[Task[A1]] = F1F2.pure(x)
|
||||
override def ap[A1, A2](ff: Initialize[Task[A1 => A2]])(
|
||||
fa: Initialize[Task[A1]]
|
||||
): Initialize[Task[A2]] =
|
||||
F1F2.ap(ff)(fa)
|
||||
|
||||
override def flatMap[A1, A2](fa: Initialize[Task[A1]])(
|
||||
f: A1 => Initialize[Task[A2]]
|
||||
): Initialize[Task[A2]] =
|
||||
val nested: Initialize[Task[Initialize[Task[A2]]]] = F1F2.map(fa)(f)
|
||||
flatten(nested)
|
||||
|
||||
override 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)) {
|
||||
case (a: Task[Initialize[Task[A1]]], data: Task[SS], f) =>
|
||||
import TaskExtra.multT2Task
|
||||
(a, data).flatMap { case (a, d) => f(a) evaluate d }
|
||||
}(AList.tuple3[Task[Initialize[Task[A1]]], Task[SS], [a] => Initialize[a] => Initialize[a]])
|
||||
|
||||
/*
|
||||
def flattenFun[S, T](
|
||||
in: Initialize[Task[S => Initialize[Task[A1]]]]
|
||||
): Initialize[S => Task[A1]] = {
|
||||
type K[L[x]] =
|
||||
AList.T3K[Task[S => Initialize[Task[A1]]], Task[SS], Initialize ~> Initialize]#l[L]
|
||||
Def.app[K, S => Task[A1]]((in, settingsData, Def.capturedTransformations)) {
|
||||
case (a: Task[S => Initialize[Task[A1]]], data: Task[SS], f) => { (s: S) =>
|
||||
import TaskExtra.multT2Task
|
||||
(a, data) flatMap { case (af, d) => f(af(s)) evaluate d }
|
||||
}
|
||||
}(AList.tuple3)
|
||||
}
|
||||
*/
|
||||
end FullInstance
|
||||
|
|
@ -9,79 +9,71 @@ package sbt
|
|||
package std
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.reflect.macros._
|
||||
import scala.quoted.*
|
||||
|
||||
import sbt.util.OptJsonWriter
|
||||
|
||||
private[sbt] object KeyMacro {
|
||||
def settingKeyImpl[T: c.WeakTypeTag](
|
||||
c: blackbox.Context
|
||||
)(description: c.Expr[String]): c.Expr[SettingKey[T]] =
|
||||
keyImpl2[T, SettingKey[T]](c) { (name, mf, ojw) =>
|
||||
c.universe.reify { SettingKey[T](name.splice, description.splice)(mf.splice, ojw.splice) }
|
||||
}
|
||||
def taskKeyImpl[T: c.WeakTypeTag](
|
||||
c: blackbox.Context
|
||||
)(description: c.Expr[String]): c.Expr[TaskKey[T]] =
|
||||
keyImpl[T, TaskKey[T]](c) { (name, mf) =>
|
||||
c.universe.reify { TaskKey[T](name.splice, description.splice)(mf.splice) }
|
||||
}
|
||||
def inputKeyImpl[T: c.WeakTypeTag](
|
||||
c: blackbox.Context
|
||||
)(description: c.Expr[String]): c.Expr[InputKey[T]] =
|
||||
keyImpl[T, InputKey[T]](c) { (name, mf) =>
|
||||
c.universe.reify { InputKey[T](name.splice, description.splice)(mf.splice) }
|
||||
}
|
||||
|
||||
def keyImpl[T: c.WeakTypeTag, S: c.WeakTypeTag](c: blackbox.Context)(
|
||||
f: (c.Expr[String], c.Expr[Manifest[T]]) => c.Expr[S]
|
||||
): c.Expr[S] =
|
||||
f(getName(c), getImplicit[Manifest[T]](c))
|
||||
|
||||
private def keyImpl2[T: c.WeakTypeTag, S: c.WeakTypeTag](c: blackbox.Context)(
|
||||
f: (c.Expr[String], c.Expr[Manifest[T]], c.Expr[OptJsonWriter[T]]) => c.Expr[S]
|
||||
): c.Expr[S] =
|
||||
f(getName(c), getImplicit[Manifest[T]](c), getImplicit[OptJsonWriter[T]](c))
|
||||
|
||||
private def getName[S: c.WeakTypeTag, T: c.WeakTypeTag](c: blackbox.Context): c.Expr[String] = {
|
||||
import c.universe._
|
||||
val enclosingValName = definingValName(
|
||||
c,
|
||||
methodName =>
|
||||
s"""$methodName must be directly assigned to a val, such as `val x = $methodName[Int]("description")`."""
|
||||
)
|
||||
c.Expr[String](Literal(Constant(enclosingValName)))
|
||||
}
|
||||
|
||||
private def getImplicit[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[T] = {
|
||||
import c.universe._
|
||||
c.Expr[T](c.inferImplicitValue(weakTypeOf[T]))
|
||||
}
|
||||
|
||||
def definingValName(c: blackbox.Context, invalidEnclosingTree: String => String): String = {
|
||||
import c.universe.{ Apply => ApplyTree, _ }
|
||||
val methodName = c.macroApplication.symbol.name
|
||||
def processName(n: Name): String =
|
||||
n.decodedName.toString.trim // trim is not strictly correct, but macros don't expose the API necessary
|
||||
@tailrec def enclosingVal(trees: List[c.Tree]): String = {
|
||||
trees match {
|
||||
case ValDef(_, name, _, _) :: _ => processName(name)
|
||||
case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs)
|
||||
// lazy val x: X = <methodName> has this form for some reason (only when the explicit type is present, though)
|
||||
case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: _ if mods.hasFlag(Flag.LAZY) =>
|
||||
processName(name)
|
||||
case _ =>
|
||||
c.error(c.enclosingPosition, invalidEnclosingTree(methodName.decodedName.toString))
|
||||
"<error>"
|
||||
private[sbt] object KeyMacro:
|
||||
def settingKeyImpl[A1: Type](
|
||||
description: Expr[String]
|
||||
)(using qctx: Quotes): Expr[SettingKey[A1]] =
|
||||
keyImpl2[A1, SettingKey[A1]]("settingKey") { (name, mf, ojw) =>
|
||||
val n = Expr(name)
|
||||
'{
|
||||
SettingKey[A1]($n, $description)($mf, $ojw)
|
||||
}
|
||||
}
|
||||
enclosingVal(enclosingTrees(c).toList)
|
||||
}
|
||||
|
||||
def enclosingTrees(c: blackbox.Context): Seq[c.Tree] =
|
||||
c.asInstanceOf[reflect.macros.runtime.Context]
|
||||
.callsiteTyper
|
||||
.context
|
||||
.enclosingContextChain
|
||||
.map(_.tree.asInstanceOf[c.Tree])
|
||||
}
|
||||
def taskKeyImpl[A1: Type](description: Expr[String])(using qctx: Quotes): Expr[TaskKey[A1]] =
|
||||
keyImpl[A1, TaskKey[A1]]("taskKey") { (name, mf) =>
|
||||
val n = Expr(name)
|
||||
'{
|
||||
TaskKey[A1]($n, $description)($mf)
|
||||
}
|
||||
}
|
||||
|
||||
def inputKeyImpl[A1: Type](description: Expr[String])(using qctx: Quotes): Expr[InputKey[A1]] =
|
||||
keyImpl[A1, InputKey[A1]]("inputKey") { (name, mf) =>
|
||||
val n = Expr(name)
|
||||
'{
|
||||
InputKey[A1]($n, $description)($mf)
|
||||
}
|
||||
}
|
||||
|
||||
private def keyImpl[A1: Type, A2: Type](methodName: String)(
|
||||
f: (String, Expr[Manifest[A1]]) => Expr[A2]
|
||||
)(using qctx: Quotes): Expr[A2] =
|
||||
val tpe = summon[Type[A1]]
|
||||
f(
|
||||
definingValName(errorMsg(methodName)),
|
||||
Expr.summon[Manifest[A1]].getOrElse(sys.error("Manifest[A] not found for $tpe"))
|
||||
)
|
||||
|
||||
private def keyImpl2[A1: Type, A2: Type](methodName: String)(
|
||||
f: (String, Expr[Manifest[A1]], Expr[OptJsonWriter[A1]]) => Expr[A2]
|
||||
)(using qctx: Quotes): Expr[A2] =
|
||||
val tpe = summon[Type[A1]]
|
||||
f(
|
||||
definingValName(errorMsg(methodName)),
|
||||
Expr.summon[Manifest[A1]].getOrElse(sys.error("Manifest[A] not found for $tpe")),
|
||||
Expr.summon[OptJsonWriter[A1]].getOrElse(sys.error("OptJsonWriter[A] not found for $tpe")),
|
||||
)
|
||||
|
||||
private def errorMsg(methodName: String): String =
|
||||
s"""$methodName must be directly assigned to a val, such as `val x = $methodName[Int]("description")`."""
|
||||
|
||||
private def definingValName(errorMsg: String)(using qctx: Quotes): String =
|
||||
val term = enclosingTerm
|
||||
if term.isValDef then term.name
|
||||
else sys.error(errorMsg)
|
||||
|
||||
def enclosingTerm(using qctx: Quotes) =
|
||||
import qctx.reflect._
|
||||
def enclosingTerm0(sym: Symbol): Symbol =
|
||||
sym match
|
||||
case sym if sym.flags is Flags.Macro => enclosingTerm0(sym.owner)
|
||||
case sym if !sym.isTerm => enclosingTerm0(sym.owner)
|
||||
case _ => sym
|
||||
enclosingTerm0(Symbol.spliceOwner)
|
||||
|
||||
end KeyMacro
|
||||
|
|
|
|||
|
|
@ -9,26 +9,18 @@ package sbt
|
|||
package std
|
||||
|
||||
import Def.Initialize
|
||||
import sbt.internal.util.Types.{ Id, idFun }
|
||||
import sbt.internal.util.AList
|
||||
import sbt.internal.util.appmacro.{
|
||||
Convert,
|
||||
Converted,
|
||||
Instance,
|
||||
LinterDSL,
|
||||
MixedBuilder,
|
||||
MonadInstance
|
||||
}
|
||||
|
||||
object InitializeInstance extends MonadInstance {
|
||||
type M[x] = Initialize[x]
|
||||
def app[K[L[x]], Z](in: K[Initialize], f: K[Id] => Z)(implicit a: AList[K]): Initialize[Z] =
|
||||
Def.app[K, Z](in)(f)(a)
|
||||
def map[S, T](in: Initialize[S], f: S => T): Initialize[T] = Def.map(in)(f)
|
||||
def flatten[T](in: Initialize[Initialize[T]]): Initialize[T] = Def.bind(in)(idFun[Initialize[T]])
|
||||
def pure[T](t: () => T): Initialize[T] = Def.pure(t)
|
||||
}
|
||||
// import sbt.internal.util.Types.{ Id, idFun }
|
||||
// import sbt.internal.util.AList
|
||||
// import sbt.internal.util.appmacro.{
|
||||
// Convert,
|
||||
// Converted,
|
||||
// Instance,
|
||||
// LinterDSL,
|
||||
// MixedBuilder,
|
||||
// MonadInstance
|
||||
// }
|
||||
|
||||
/*
|
||||
import reflect.macros._
|
||||
|
||||
object InitializeConvert extends Convert {
|
||||
|
|
@ -36,8 +28,8 @@ object InitializeConvert extends Convert {
|
|||
nme match {
|
||||
case InputWrapper.WrapInitName => convert[T](c)(in)
|
||||
case InputWrapper.WrapTaskName | InputWrapper.WrapInitTaskName => failTask[c.type](c)(in.pos)
|
||||
case InputWrapper.WrapPreviousName => failPrevious[c.type](c)(in.pos)
|
||||
case _ => Converted.NotApplicable
|
||||
case InputWrapper.WrapPreviousName => failPrevious[c.type](c)(in.pos)
|
||||
case _ => Converted.NotApplicable
|
||||
}
|
||||
|
||||
private def convert[T: c.WeakTypeTag](c: blackbox.Context)(in: c.Tree): Converted[c.type] = {
|
||||
|
|
@ -72,3 +64,4 @@ object SettingMacro {
|
|||
Instance.idTransform[c.type]
|
||||
)
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -11,11 +11,12 @@ import sbt.SettingKey
|
|||
import sbt.dsl.LinterLevel
|
||||
import sbt.dsl.LinterLevel.{ Abort, Warn }
|
||||
import sbt.internal.util.Terminal
|
||||
import sbt.internal.util.appmacro.{ Convert, LinterDSL }
|
||||
// import sbt.internal.util.appmacro.{ Convert, LinterDSL }
|
||||
|
||||
import scala.io.AnsiColor
|
||||
import scala.reflect.macros.blackbox
|
||||
|
||||
/*
|
||||
abstract class BaseTaskLinterDSL extends LinterDSL {
|
||||
def isDynamicTask: Boolean
|
||||
def convert: Convert
|
||||
|
|
@ -29,19 +30,19 @@ abstract class BaseTaskLinterDSL extends LinterDSL {
|
|||
val initializeType = typeOf[sbt.Def.Initialize[_]]
|
||||
|
||||
/*
|
||||
* Lints a task tree.
|
||||
*
|
||||
* @param insideIf indicates whether or not the current tree is enclosed in an if statement.
|
||||
* It is generally illegal to call `.value` on a task within such a tree unless
|
||||
* the tree has been annotated with `@sbtUnchecked`.
|
||||
* @param insideAnon indicates whether or not the current tree is enclosed in an anonymous
|
||||
* function. It is generally illegal to call `.value` on a task within such
|
||||
* a tree unless the tree has been annotated with `@sbtUnchecked`.
|
||||
* @param uncheckedWrapper an optional tree that is provided to lint a tree in the form:
|
||||
* `tree.value: @sbtUnchecked` for some tree. This can be used to
|
||||
* prevent the linter from rejecting task evaluation within a
|
||||
* conditional or an anonymous function.
|
||||
*/
|
||||
* Lints a task tree.
|
||||
*
|
||||
* @param insideIf indicates whether or not the current tree is enclosed in an if statement.
|
||||
* It is generally illegal to call `.value` on a task within such a tree unless
|
||||
* the tree has been annotated with `@sbtUnchecked`.
|
||||
* @param insideAnon indicates whether or not the current tree is enclosed in an anonymous
|
||||
* function. It is generally illegal to call `.value` on a task within such
|
||||
* a tree unless the tree has been annotated with `@sbtUnchecked`.
|
||||
* @param uncheckedWrapper an optional tree that is provided to lint a tree in the form:
|
||||
* `tree.value: @sbtUnchecked` for some tree. This can be used to
|
||||
* prevent the linter from rejecting task evaluation within a
|
||||
* conditional or an anonymous function.
|
||||
*/
|
||||
class traverser(insideIf: Boolean, insideAnon: Boolean, uncheckedWrapper: Option[Tree])
|
||||
extends Traverser {
|
||||
|
||||
|
|
@ -128,12 +129,12 @@ abstract class BaseTaskLinterDSL extends LinterDSL {
|
|||
case Block(stmts, expr) =>
|
||||
if (!isDynamicTask) {
|
||||
/* The missing .value analysis is dumb on purpose because it's expensive.
|
||||
* Detecting valid use cases of idents whose type is an sbt key is difficult
|
||||
* and dangerous because we may miss some corner cases. Instead, we report
|
||||
* on the easiest cases in which we are certain that the user does not want
|
||||
* to have a stale key reference. Those are idents in the rhs of a val definition
|
||||
* whose name is `_` and those idents that are in statement position inside blocks.
|
||||
*/
|
||||
* Detecting valid use cases of idents whose type is an sbt key is difficult
|
||||
* and dangerous because we may miss some corner cases. Instead, we report
|
||||
* on the easiest cases in which we are certain that the user does not want
|
||||
* to have a stale key reference. Those are idents in the rhs of a val definition
|
||||
* whose name is `_` and those idents that are in statement position inside blocks.
|
||||
*/
|
||||
stmts.foreach {
|
||||
// TODO: Consider using unused names analysis to be able to report on more cases
|
||||
case ValDef(_, valName, _, rhs) if valName == termNames.WILDCARD =>
|
||||
|
|
@ -217,7 +218,7 @@ object TaskLinterDSLFeedback {
|
|||
| Regular tasks always evaluate task dependencies (`.value`) regardless of `if` expressions.
|
||||
|$SolutionHeader:
|
||||
| 1. Use a conditional task `Def.taskIf(...)` to evaluate it when the `if` predicate is true or false.
|
||||
| 2. Or turn the task body into a single `if` expression; the task is then auto-converted to a conditional task.
|
||||
| 2. Or turn the task body into a single `if` expression; the task is then auto-converted to a conditional task.
|
||||
| 3. Or make the static evaluation explicit by declaring `$task.value` outside the `if` expression.
|
||||
| 4. If you still want to force the static lookup, you may annotate the task lookup with `@sbtUnchecked`, e.g. `($task.value: @sbtUnchecked)`.
|
||||
| 5. Add `import sbt.dsl.LinterLevel.Ignore` to your build file to disable all task linting.
|
||||
|
|
@ -241,3 +242,4 @@ object TaskLinterDSLFeedback {
|
|||
| 2. Add `import sbt.dsl.LinterLevel.Ignore` to your build file to disable all task linting.
|
||||
""".stripMargin
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -9,81 +9,46 @@ package sbt
|
|||
package std
|
||||
|
||||
import Def.{ Initialize, Setting }
|
||||
import sbt.internal.util.Types.{ Id, const, idFun }
|
||||
import sbt.util.{ Applicative, Monad }
|
||||
import sbt.internal.util.Types.{ Id, Compose, const, idFun }
|
||||
import sbt.internal.util.appmacro.{
|
||||
Cont,
|
||||
ContextUtil,
|
||||
Converted,
|
||||
Instance,
|
||||
LinterDSL,
|
||||
MixedBuilder,
|
||||
MonadInstance
|
||||
Convert,
|
||||
// Instance,
|
||||
// LinterDSL,
|
||||
// MixedBuilder,
|
||||
// MonadInstance
|
||||
}
|
||||
import Instance.Transform
|
||||
import sbt.internal.util.complete.{ DefaultParsers, Parser }
|
||||
// import Instance.Transform
|
||||
import sbt.internal.util.{ AList, LinePosition, NoPosition, SourcePosition, ~> }
|
||||
|
||||
import language.experimental.macros
|
||||
import scala.annotation.tailrec
|
||||
import reflect.macros._
|
||||
import scala.reflect.internal.util.UndefinedPosition
|
||||
import scala.quoted.*
|
||||
|
||||
/** Instance for the monad/applicative functor for plain Tasks. */
|
||||
object TaskInstance extends MonadInstance {
|
||||
/*
|
||||
object TaskInstance:
|
||||
import TaskExtra._
|
||||
|
||||
final type M[x] = Task[x]
|
||||
def app[K[L[x]], Z](in: K[Task], f: K[Id] => Z)(implicit a: AList[K]): Task[Z] = in map f
|
||||
def map[S, T](in: Task[S], f: S => T): Task[T] = in map f
|
||||
def flatten[T](in: Task[Task[T]]): Task[T] = in flatMap idFun[Task[T]]
|
||||
def pure[T](t: () => T): Task[T] = toTask(t)
|
||||
}
|
||||
object ParserInstance extends Instance {
|
||||
import sbt.internal.util.Classes.Applicative
|
||||
private[this] implicit val parserApplicative: Applicative[M] = new Applicative[M] {
|
||||
def apply[S, T](f: M[S => T], v: M[S]): M[T] = s => (f(s) ~ v(s)) map { case (a, b) => a(b) }
|
||||
def pure[S](s: => S) = const(Parser.success(s))
|
||||
def map[S, T](f: S => T, v: M[S]) = s => v(s).map(f)
|
||||
}
|
||||
given taskMonad: Monad[Task] with
|
||||
type F[a] = Task[a]
|
||||
override def pure[A1](a: () => A1): Task[A1] = toTask(a)
|
||||
|
||||
final type M[x] = State => Parser[x]
|
||||
def app[K[L[x]], Z](in: K[M], f: K[Id] => Z)(implicit a: AList[K]): M[Z] = a.apply(in, f)
|
||||
def map[S, T](in: M[S], f: S => T): M[T] = s => in(s) map f
|
||||
def pure[T](t: () => T): State => Parser[T] = const(DefaultParsers.success(t()))
|
||||
}
|
||||
|
||||
/** Composes the Task and Initialize Instances to provide an Instance for [T] Initialize[Task[T]].*/
|
||||
object FullInstance
|
||||
extends Instance.Composed[Initialize, Task](InitializeInstance, TaskInstance)
|
||||
with MonadInstance {
|
||||
type SS = sbt.internal.util.Settings[Scope]
|
||||
val settingsData = TaskKey[SS](
|
||||
"settings-data",
|
||||
"Provides access to the project data for the build.",
|
||||
KeyRanks.DTask
|
||||
)
|
||||
|
||||
def flatten[T](in: Initialize[Task[Initialize[Task[T]]]]): Initialize[Task[T]] = {
|
||||
type K[L[x]] = AList.T3K[Task[Initialize[Task[T]]], Task[SS], Initialize ~> Initialize]#l[L]
|
||||
Def.app[K, Task[T]]((in, settingsData, Def.capturedTransformations)) {
|
||||
case (a: Task[Initialize[Task[T]]], data: Task[SS], f) =>
|
||||
import TaskExtra.multT2Task
|
||||
(a, data) flatMap { case (a, d) => f(a) evaluate d }
|
||||
}(AList.tuple3)
|
||||
}
|
||||
|
||||
def flattenFun[S, T](in: Initialize[Task[S => Initialize[Task[T]]]]): Initialize[S => Task[T]] = {
|
||||
type K[L[x]] =
|
||||
AList.T3K[Task[S => Initialize[Task[T]]], Task[SS], Initialize ~> Initialize]#l[L]
|
||||
Def.app[K, S => Task[T]]((in, settingsData, Def.capturedTransformations)) {
|
||||
case (a: Task[S => Initialize[Task[T]]], data: Task[SS], f) => { (s: S) =>
|
||||
import TaskExtra.multT2Task
|
||||
(a, data) flatMap { case (af, d) => f(af(s)) evaluate d }
|
||||
override def ap[A1, A2](ff: Task[A1 => A2])(in: Task[A1]): Task[A2] =
|
||||
multT2Task((in, ff)).map { case (x, f) =>
|
||||
f(x)
|
||||
}
|
||||
}(AList.tuple3)
|
||||
}
|
||||
}
|
||||
|
||||
object TaskMacro {
|
||||
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]])
|
||||
end TaskInstance
|
||||
*/
|
||||
|
||||
object TaskMacro:
|
||||
final val AssignInitName = "set"
|
||||
final val Append1InitName = "append1"
|
||||
final val AppendNInitName = "appendN"
|
||||
|
|
@ -100,41 +65,44 @@ object TaskMacro {
|
|||
"""`<<=` operator is removed. Use `key := { x.value }` or `key ~= (old => { newValue })`.
|
||||
|See https://www.scala-sbt.org/1.x/docs/Migrating-from-sbt-013x.html""".stripMargin
|
||||
|
||||
import LinterDSL.{ Empty => EmptyLinter }
|
||||
type F[x] = Initialize[Task[x]]
|
||||
|
||||
def taskMacroImpl[T: c.WeakTypeTag](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[T]): c.Expr[Initialize[Task[T]]] = {
|
||||
import c.universe._
|
||||
t.tree match {
|
||||
// the tree matches `if` and only `if`
|
||||
case If(cond, thenp, elsep) =>
|
||||
c.Expr[Initialize[Task[T]]](mkIfS[T](c)(cond, thenp, elsep))
|
||||
object ContSyntax extends Cont
|
||||
import ContSyntax.*
|
||||
|
||||
// import LinterDSL.{ Empty => EmptyLinter }
|
||||
|
||||
def taskMacroImpl[A1: Type](t: Expr[A1])(using qctx: Quotes): Expr[Initialize[Task[A1]]] =
|
||||
// import qctx.reflect.*
|
||||
t match
|
||||
case '{ if ($cond) then $thenp else $elsep } => mkIfS[A1](t)
|
||||
case _ =>
|
||||
Instance.contImpl[T, Id](c, FullInstance, FullConvert, MixedBuilder, TaskLinterDSL)(
|
||||
Left(t),
|
||||
Instance.idTransform[c.type]
|
||||
)
|
||||
}
|
||||
}
|
||||
val convert1: Convert[qctx.type] = new FullConvert(qctx)
|
||||
convert1.contMapN[A1, F, Id](t, convert1.idTransform)
|
||||
// Instance.contImpl[A1, Id](c, FullInstance, FullConvert, MixedBuilder, TaskLinterDSL)(
|
||||
// Left(t),
|
||||
// Instance.idTransform[c.type]
|
||||
// )
|
||||
|
||||
def mkIfS[A: c.WeakTypeTag](
|
||||
c: blackbox.Context
|
||||
)(cond: c.Tree, thenp: c.Tree, elsep: c.Tree): c.Tree = {
|
||||
import c.universe._
|
||||
val AA = implicitly[c.WeakTypeTag[A]].tpe
|
||||
q"""_root_.sbt.Def.ifS[$AA](_root_.sbt.Def.task($cond))(_root_.sbt.Def.task[$AA]($thenp: $AA))(_root_.sbt.Def.task[$AA]($elsep: $AA))"""
|
||||
}
|
||||
def mkIfS[A1: Type](using
|
||||
qctx: Quotes
|
||||
)(t: Expr[A1]): Expr[Initialize[Task[A1]]] =
|
||||
t match
|
||||
case '{ if ($cond) then $thenp else $elsep } =>
|
||||
'{
|
||||
Def.ifS[A1](Def.task($cond))(Def.task[A1]($thenp))(Def.task[A1]($elsep))
|
||||
}
|
||||
|
||||
def taskDynMacroImpl[T: c.WeakTypeTag](
|
||||
/*
|
||||
def taskDynMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[Initialize[Task[T]]]): c.Expr[Initialize[Task[T]]] =
|
||||
Instance.contImpl[T, Id](c, FullInstance, FullConvert, MixedBuilder, TaskDynLinterDSL)(
|
||||
)(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[Task[A1]]] =
|
||||
Instance.contImpl[A1, Id](c, FullInstance, FullConvert, MixedBuilder, TaskDynLinterDSL)(
|
||||
Right(t),
|
||||
Instance.idTransform[c.type]
|
||||
)
|
||||
|
||||
def taskIfMacroImpl[A: c.WeakTypeTag](
|
||||
def taskIfMacroImpl[A: Type](
|
||||
c: blackbox.Context
|
||||
)(a: c.Expr[A]): c.Expr[Initialize[Task[A]]] = {
|
||||
import c.universe._
|
||||
|
|
@ -148,58 +116,58 @@ object TaskMacro {
|
|||
}
|
||||
|
||||
/** Implementation of := macro for settings. */
|
||||
def settingAssignMacroImpl[T: c.WeakTypeTag](
|
||||
def settingAssignMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[T]): c.Expr[Setting[T]] = {
|
||||
val init = SettingMacro.settingMacroImpl[T](c)(v)
|
||||
)(v: c.Expr[A1]): c.Expr[Setting[A1]] = {
|
||||
val init = SettingMacro.settingMacroImpl[A1](c)(v)
|
||||
val assign = transformMacroImpl(c)(init.tree)(AssignInitName)
|
||||
c.Expr[Setting[T]](assign)
|
||||
c.Expr[Setting[A1]](assign)
|
||||
}
|
||||
|
||||
/** Implementation of := macro for tasks. */
|
||||
def taskAssignMacroImpl[T: c.WeakTypeTag](
|
||||
def taskAssignMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[T]): c.Expr[Setting[Task[T]]] = {
|
||||
val init = taskMacroImpl[T](c)(v)
|
||||
)(v: c.Expr[A1]): c.Expr[Setting[Task[A1]]] = {
|
||||
val init = taskMacroImpl[A1](c)(v)
|
||||
val assign = transformMacroImpl(c)(init.tree)(AssignInitName)
|
||||
c.Expr[Setting[Task[T]]](assign)
|
||||
c.Expr[Setting[Task[A1]]](assign)
|
||||
}
|
||||
|
||||
// Error macros (Restligeist)
|
||||
// These macros are there just so we can fail old operators like `<<=` and provide useful migration information.
|
||||
|
||||
def fakeSettingAssignPosition[T: c.WeakTypeTag](c: blackbox.Context)(
|
||||
@deprecated("unused", "") app: c.Expr[Initialize[T]]
|
||||
): c.Expr[Setting[T]] =
|
||||
ContextUtil.selectMacroImpl[Setting[T]](c)((_, pos) => c.abort(pos, assignMigration))
|
||||
def fakeSettingAssignPosition[A1: Type](c: blackbox.Context)(
|
||||
@deprecated("unused", "") app: c.Expr[Initialize[A1]]
|
||||
): c.Expr[Setting[A1]] =
|
||||
ContextUtil.selectMacroImpl[Setting[A1]](c)((_, pos) => c.abort(pos, assignMigration))
|
||||
|
||||
def fakeSettingAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](
|
||||
def fakeSettingAppend1Position[S: Type, V: Type](
|
||||
c: blackbox.Context
|
||||
)(@deprecated("unused", "") v: c.Expr[Initialize[V]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Value[S, V]]
|
||||
): c.Expr[Setting[S]] =
|
||||
ContextUtil.selectMacroImpl[Setting[S]](c)((_, pos) => c.abort(pos, append1Migration))
|
||||
|
||||
def fakeSettingAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](
|
||||
def fakeSettingAppendNPosition[S: Type, V: Type](
|
||||
c: blackbox.Context
|
||||
)(@deprecated("unused", "") vs: c.Expr[Initialize[V]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Values[S, V]]
|
||||
): c.Expr[Setting[S]] =
|
||||
ContextUtil.selectMacroImpl[Setting[S]](c)((_, pos) => c.abort(pos, appendNMigration))
|
||||
|
||||
def fakeItaskAssignPosition[T: c.WeakTypeTag](c: blackbox.Context)(
|
||||
@deprecated("unused", "") app: c.Expr[Initialize[Task[T]]]
|
||||
): c.Expr[Setting[Task[T]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[T]]](c)((_, pos) => c.abort(pos, assignMigration))
|
||||
def fakeItaskAssignPosition[A1: Type](c: blackbox.Context)(
|
||||
@deprecated("unused", "") app: c.Expr[Initialize[Task[A1]]]
|
||||
): c.Expr[Setting[Task[A1]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[A1]]](c)((_, pos) => c.abort(pos, assignMigration))
|
||||
|
||||
def fakeTaskAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](
|
||||
def fakeTaskAppend1Position[S: Type, V: Type](
|
||||
c: blackbox.Context
|
||||
)(@deprecated("unused", "") v: c.Expr[Initialize[Task[V]]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Value[S, V]]
|
||||
): c.Expr[Setting[Task[S]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[S]]](c)((_, pos) => c.abort(pos, append1Migration))
|
||||
|
||||
def fakeTaskAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](
|
||||
def fakeTaskAppendNPosition[S: Type, V: Type](
|
||||
c: blackbox.Context
|
||||
)(@deprecated("unused", "") vs: c.Expr[Initialize[Task[V]]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Values[S, V]]
|
||||
|
|
@ -209,68 +177,68 @@ object TaskMacro {
|
|||
// Implementations of <<= macro variations for tasks and settings.
|
||||
// These just get the source position of the call site.
|
||||
|
||||
def itaskAssignPosition[T: c.WeakTypeTag](
|
||||
def itaskAssignPosition[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(app: c.Expr[Initialize[Task[T]]]): c.Expr[Setting[Task[T]]] =
|
||||
)(app: c.Expr[Initialize[Task[A1]]]): c.Expr[Setting[Task[A1]]] =
|
||||
settingAssignPosition(c)(app)
|
||||
|
||||
def taskAssignPositionT[T: c.WeakTypeTag](
|
||||
def taskAssignPositionT[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(app: c.Expr[Task[T]]): c.Expr[Setting[Task[T]]] =
|
||||
)(app: c.Expr[Task[A1]]): c.Expr[Setting[Task[A1]]] =
|
||||
itaskAssignPosition(c)(c.universe.reify { Def.valueStrict(app.splice) })
|
||||
|
||||
def taskAssignPositionPure[T: c.WeakTypeTag](
|
||||
def taskAssignPositionPure[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(app: c.Expr[T]): c.Expr[Setting[Task[T]]] =
|
||||
)(app: c.Expr[A1]): c.Expr[Setting[Task[A1]]] =
|
||||
taskAssignPositionT(c)(c.universe.reify { TaskExtra.constant(app.splice) })
|
||||
|
||||
def taskTransformPosition[S: c.WeakTypeTag](
|
||||
def taskTransformPosition[S: Type](
|
||||
c: blackbox.Context
|
||||
)(f: c.Expr[S => S]): c.Expr[Setting[Task[S]]] =
|
||||
c.Expr[Setting[Task[S]]](transformMacroImpl(c)(f.tree)(TransformInitName))
|
||||
|
||||
def settingTransformPosition[S: c.WeakTypeTag](
|
||||
def settingTransformPosition[S: Type](
|
||||
c: blackbox.Context
|
||||
)(f: c.Expr[S => S]): c.Expr[Setting[S]] =
|
||||
c.Expr[Setting[S]](transformMacroImpl(c)(f.tree)(TransformInitName))
|
||||
|
||||
def itaskTransformPosition[S: c.WeakTypeTag](
|
||||
def itaskTransformPosition[S: Type](
|
||||
c: blackbox.Context
|
||||
)(f: c.Expr[S => S]): c.Expr[Setting[S]] =
|
||||
c.Expr[Setting[S]](transformMacroImpl(c)(f.tree)(TransformInitName))
|
||||
|
||||
def settingAssignPure[T: c.WeakTypeTag](c: blackbox.Context)(app: c.Expr[T]): c.Expr[Setting[T]] =
|
||||
def settingAssignPure[A1: Type](c: blackbox.Context)(app: c.Expr[A1]): c.Expr[Setting[A1]] =
|
||||
settingAssignPosition(c)(c.universe.reify { Def.valueStrict(app.splice) })
|
||||
|
||||
def settingAssignPosition[T: c.WeakTypeTag](
|
||||
def settingAssignPosition[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(app: c.Expr[Initialize[T]]): c.Expr[Setting[T]] =
|
||||
c.Expr[Setting[T]](transformMacroImpl(c)(app.tree)(AssignInitName))
|
||||
)(app: c.Expr[Initialize[A1]]): c.Expr[Setting[A1]] =
|
||||
c.Expr[Setting[A1]](transformMacroImpl(c)(app.tree)(AssignInitName))
|
||||
|
||||
/** Implementation of := macro for tasks. */
|
||||
def inputTaskAssignMacroImpl[T: c.WeakTypeTag](
|
||||
def inputTaskAssignMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[T]): c.Expr[Setting[InputTask[T]]] = {
|
||||
val init = inputTaskMacroImpl[T](c)(v)
|
||||
)(v: c.Expr[A1]): c.Expr[Setting[InputTask[A1]]] = {
|
||||
val init = inputTaskMacroImpl[A1](c)(v)
|
||||
val assign = transformMacroImpl(c)(init.tree)(AssignInitName)
|
||||
c.Expr[Setting[InputTask[T]]](assign)
|
||||
c.Expr[Setting[InputTask[A1]]](assign)
|
||||
}
|
||||
|
||||
/** Implementation of += macro for tasks. */
|
||||
def taskAppend1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](
|
||||
def taskAppend1Impl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[U])(a: c.Expr[Append.Value[T, U]]): c.Expr[Setting[Task[T]]] = {
|
||||
)(v: c.Expr[U])(a: c.Expr[Append.Value[A1, U]]): c.Expr[Setting[Task[A1]]] = {
|
||||
val init = taskMacroImpl[U](c)(v)
|
||||
val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName)
|
||||
c.Expr[Setting[Task[T]]](append)
|
||||
c.Expr[Setting[Task[A1]]](append)
|
||||
}
|
||||
|
||||
/** Implementation of += macro for settings. */
|
||||
def settingAppend1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](
|
||||
def settingAppend1Impl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[U])(a: c.Expr[Append.Value[T, U]]): c.Expr[Setting[T]] = {
|
||||
)(v: c.Expr[U])(a: c.Expr[Append.Value[A1, U]]): c.Expr[Setting[A1]] = {
|
||||
import c.universe._
|
||||
val ttpe = c.weakTypeOf[T]
|
||||
val ttpe = c.weakTypeOf[A1]
|
||||
val typeArgs = ttpe.typeArgs
|
||||
v.tree.tpe match {
|
||||
// To allow Initialize[Task[A]] in the position of += RHS, we're going to call "taskValue" automatically.
|
||||
|
|
@ -283,71 +251,71 @@ object TaskMacro {
|
|||
TypeApply(Select(preT, TermName("+=").encodedName), TypeTree(typeArgs.head) :: Nil),
|
||||
Select(v.tree, TermName("taskValue").encodedName) :: Nil
|
||||
)
|
||||
c.Expr[Setting[T]](tree)
|
||||
c.Expr[Setting[A1]](tree)
|
||||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
case _ =>
|
||||
val init = SettingMacro.settingMacroImpl[U](c)(v)
|
||||
val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName)
|
||||
c.Expr[Setting[T]](append)
|
||||
c.Expr[Setting[A1]](append)
|
||||
}
|
||||
}
|
||||
|
||||
/** Implementation of ++= macro for tasks. */
|
||||
def taskAppendNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](
|
||||
def taskAppendNImpl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(vs: c.Expr[U])(a: c.Expr[Append.Values[T, U]]): c.Expr[Setting[Task[T]]] = {
|
||||
)(vs: c.Expr[U])(a: c.Expr[Append.Values[A1, U]]): c.Expr[Setting[Task[A1]]] = {
|
||||
val init = taskMacroImpl[U](c)(vs)
|
||||
val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName)
|
||||
c.Expr[Setting[Task[T]]](append)
|
||||
c.Expr[Setting[Task[A1]]](append)
|
||||
}
|
||||
|
||||
/** Implementation of ++= macro for settings. */
|
||||
def settingAppendNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](
|
||||
def settingAppendNImpl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(vs: c.Expr[U])(a: c.Expr[Append.Values[T, U]]): c.Expr[Setting[T]] = {
|
||||
)(vs: c.Expr[U])(a: c.Expr[Append.Values[A1, U]]): c.Expr[Setting[A1]] = {
|
||||
val init = SettingMacro.settingMacroImpl[U](c)(vs)
|
||||
val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName)
|
||||
c.Expr[Setting[T]](append)
|
||||
c.Expr[Setting[A1]](append)
|
||||
}
|
||||
|
||||
/** Implementation of -= macro for tasks. */
|
||||
def taskRemove1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](
|
||||
def taskRemove1Impl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[U])(r: c.Expr[Remove.Value[T, U]]): c.Expr[Setting[Task[T]]] = {
|
||||
)(v: c.Expr[U])(r: c.Expr[Remove.Value[A1, U]]): c.Expr[Setting[Task[A1]]] = {
|
||||
val init = taskMacroImpl[U](c)(v)
|
||||
val remove = removeMacroImpl(c)(init.tree, r.tree)(Remove1InitName)
|
||||
c.Expr[Setting[Task[T]]](remove)
|
||||
c.Expr[Setting[Task[A1]]](remove)
|
||||
}
|
||||
|
||||
/** Implementation of -= macro for settings. */
|
||||
def settingRemove1Impl[T: c.WeakTypeTag, U: c.WeakTypeTag](
|
||||
def settingRemove1Impl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[U])(r: c.Expr[Remove.Value[T, U]]): c.Expr[Setting[T]] = {
|
||||
)(v: c.Expr[U])(r: c.Expr[Remove.Value[A1, U]]): c.Expr[Setting[A1]] = {
|
||||
val init = SettingMacro.settingMacroImpl[U](c)(v)
|
||||
val remove = removeMacroImpl(c)(init.tree, r.tree)(Remove1InitName)
|
||||
c.Expr[Setting[T]](remove)
|
||||
c.Expr[Setting[A1]](remove)
|
||||
}
|
||||
|
||||
/** Implementation of --= macro for tasks. */
|
||||
def taskRemoveNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](
|
||||
def taskRemoveNImpl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(vs: c.Expr[U])(r: c.Expr[Remove.Values[T, U]]): c.Expr[Setting[Task[T]]] = {
|
||||
)(vs: c.Expr[U])(r: c.Expr[Remove.Values[A1, U]]): c.Expr[Setting[Task[A1]]] = {
|
||||
val init = taskMacroImpl[U](c)(vs)
|
||||
val remove = removeMacroImpl(c)(init.tree, r.tree)(RemoveNInitName)
|
||||
c.Expr[Setting[Task[T]]](remove)
|
||||
c.Expr[Setting[Task[A1]]](remove)
|
||||
}
|
||||
|
||||
/** Implementation of --= macro for settings. */
|
||||
def settingRemoveNImpl[T: c.WeakTypeTag, U: c.WeakTypeTag](
|
||||
def settingRemoveNImpl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(vs: c.Expr[U])(r: c.Expr[Remove.Values[T, U]]): c.Expr[Setting[T]] = {
|
||||
)(vs: c.Expr[U])(r: c.Expr[Remove.Values[A1, U]]): c.Expr[Setting[A1]] = {
|
||||
val init = SettingMacro.settingMacroImpl[U](c)(vs)
|
||||
val remove = removeMacroImpl(c)(init.tree, r.tree)(RemoveNInitName)
|
||||
c.Expr[Setting[T]](remove)
|
||||
c.Expr[Setting[A1]](remove)
|
||||
}
|
||||
|
||||
private[this] def appendMacroImpl(
|
||||
private[A1his] def appendMacroImpl(
|
||||
c: blackbox.Context
|
||||
)(init: c.Tree, append: c.Tree)(newName: String): c.Tree = {
|
||||
import c.universe._
|
||||
|
|
@ -364,7 +332,7 @@ object TaskMacro {
|
|||
}
|
||||
}
|
||||
|
||||
private[this] def removeMacroImpl(
|
||||
private[A1his] def removeMacroImpl(
|
||||
c: blackbox.Context
|
||||
)(init: c.Tree, remove: c.Tree)(newName: String): c.Tree = {
|
||||
import c.universe._
|
||||
|
|
@ -381,7 +349,7 @@ object TaskMacro {
|
|||
}
|
||||
}
|
||||
|
||||
private[this] def transformMacroImpl(c: blackbox.Context)(init: c.Tree)(
|
||||
private[A1his] def transformMacroImpl(c: blackbox.Context)(init: c.Tree)(
|
||||
newName: String
|
||||
): c.Tree = {
|
||||
import c.universe._
|
||||
|
|
@ -396,7 +364,7 @@ object TaskMacro {
|
|||
)
|
||||
}
|
||||
|
||||
private[this] def sourcePosition(c: blackbox.Context): c.Expr[SourcePosition] = {
|
||||
private[A1his] def sourcePosition(c: blackbox.Context): c.Expr[SourcePosition] = {
|
||||
import c.universe.reify
|
||||
val pos = c.enclosingPosition
|
||||
if (!pos.isInstanceOf[UndefinedPosition] && pos.line >= 0 && pos.source != null) {
|
||||
|
|
@ -404,11 +372,10 @@ object TaskMacro {
|
|||
val name = constant[String](c, settingSource(c, f.path, f.name))
|
||||
val line = constant[Int](c, pos.line)
|
||||
reify { LinePosition(name.splice, line.splice) }
|
||||
} else
|
||||
reify { NoPosition }
|
||||
} else reify { NoPosition }
|
||||
}
|
||||
|
||||
private[this] def settingSource(c: blackbox.Context, path: String, name: String): String = {
|
||||
private[A1his] def settingSource(c: blackbox.Context, path: String, name: String): String = {
|
||||
@tailrec def inEmptyPackage(s: c.Symbol): Boolean = s != c.universe.NoSymbol && (
|
||||
s.owner == c.mirror.EmptyPackage || s.owner == c.mirror.EmptyPackageClass || inEmptyPackage(
|
||||
s.owner
|
||||
|
|
@ -421,24 +388,24 @@ object TaskMacro {
|
|||
}
|
||||
}
|
||||
|
||||
private[this] def constant[T: c.TypeTag](c: blackbox.Context, t: T): c.Expr[T] = {
|
||||
private[A1his] def constant[A1: c.TypeTag](c: blackbox.Context, t: T): c.Expr[A1] = {
|
||||
import c.universe._
|
||||
c.Expr[T](Literal(Constant(t)))
|
||||
c.Expr[A1](Literal(Constant(t)))
|
||||
}
|
||||
|
||||
def inputTaskMacroImpl[T: c.WeakTypeTag](
|
||||
def inputTaskMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[T]): c.Expr[Initialize[InputTask[T]]] =
|
||||
inputTaskMacro0[T](c)(t)
|
||||
)(t: c.Expr[A1]): c.Expr[Initialize[InputTask[A1]]] =
|
||||
inputTaskMacro0[A1](c)(t)
|
||||
|
||||
def inputTaskDynMacroImpl[T: c.WeakTypeTag](
|
||||
def inputTaskDynMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[Initialize[Task[T]]]): c.Expr[Initialize[InputTask[T]]] =
|
||||
inputTaskDynMacro0[T](c)(t)
|
||||
)(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[InputTask[A1]]] =
|
||||
inputTaskDynMacro0[A1](c)(t)
|
||||
|
||||
private[this] def inputTaskMacro0[T: c.WeakTypeTag](
|
||||
private[A1his] def inputTaskMacro0[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[T]): c.Expr[Initialize[InputTask[T]]] =
|
||||
)(t: c.Expr[A1]): c.Expr[Initialize[InputTask[A1]]] =
|
||||
iInitializeMacro(c)(t) { et =>
|
||||
val pt = iParserMacro(c)(et) { pt =>
|
||||
iTaskMacro(c)(pt)
|
||||
|
|
@ -446,77 +413,77 @@ object TaskMacro {
|
|||
c.universe.reify { InputTask.make(pt.splice) }
|
||||
}
|
||||
|
||||
private[this] def iInitializeMacro[M[_], T](c: blackbox.Context)(t: c.Expr[T])(
|
||||
f: c.Expr[T] => c.Expr[M[T]]
|
||||
)(implicit tt: c.WeakTypeTag[T], mt: c.WeakTypeTag[M[T]]): c.Expr[Initialize[M[T]]] = {
|
||||
val inner: Transform[c.type, M] = (in: c.Tree) => f(c.Expr[T](in)).tree
|
||||
val cond = c.Expr[T](conditionInputTaskTree(c)(t.tree))
|
||||
private[A1his] def iInitializeMacro[M[_], T](c: blackbox.Context)(t: c.Expr[A1])(
|
||||
f: c.Expr[A1] => c.Expr[M[A1]]
|
||||
)(implicit tt: Type[A1], mt: Type[M[A1]]): c.Expr[Initialize[M[A1]]] = {
|
||||
val inner: Transform[c.type, M] = (in: c.Tree) => f(c.Expr[A1](in)).tree
|
||||
val cond = c.Expr[A1](conditionInputTaskTree(c)(t.tree))
|
||||
Instance
|
||||
.contImpl[T, M](c, InitializeInstance, InputInitConvert, MixedBuilder, EmptyLinter)(
|
||||
.contImpl[A1, M](c, InitializeInstance, InputInitConvert, MixedBuilder, EmptyLinter)(
|
||||
Left(cond),
|
||||
inner
|
||||
)
|
||||
}
|
||||
|
||||
private[this] def conditionInputTaskTree(c: blackbox.Context)(t: c.Tree): c.Tree = {
|
||||
private[A1his] def conditionInputTaskTree(c: blackbox.Context)(t: c.Tree): c.Tree = {
|
||||
import c.universe._
|
||||
import InputWrapper._
|
||||
def wrapInitTask[T: c.WeakTypeTag](tree: Tree) = {
|
||||
val e = c.Expr[Initialize[Task[T]]](tree)
|
||||
wrapTask[T](c)(wrapInit[Task[T]](c)(e, tree.pos), tree.pos).tree
|
||||
def wrapInitTask[A1: Type](tree: Tree) = {
|
||||
val e = c.Expr[Initialize[Task[A1]]](tree)
|
||||
wrapTask[A1](c)(wrapInit[Task[A1]](c)(e, tree.pos), tree.pos).tree
|
||||
}
|
||||
def wrapInitParser[T: c.WeakTypeTag](tree: Tree) = {
|
||||
val e = c.Expr[Initialize[State => Parser[T]]](tree)
|
||||
ParserInput.wrap[T](c)(wrapInit[State => Parser[T]](c)(e, tree.pos), tree.pos).tree
|
||||
def wrapInitParser[A1: Type](tree: Tree) = {
|
||||
val e = c.Expr[Initialize[State => Parser[A1]]](tree)
|
||||
ParserInput.wrap[A1](c)(wrapInit[State => Parser[A1]](c)(e, tree.pos), tree.pos).tree
|
||||
}
|
||||
def wrapInitInput[T: c.WeakTypeTag](tree: Tree) = {
|
||||
val e = c.Expr[Initialize[InputTask[T]]](tree)
|
||||
wrapInput[T](wrapInit[InputTask[T]](c)(e, tree.pos).tree)
|
||||
def wrapInitInput[A1: Type](tree: Tree) = {
|
||||
val e = c.Expr[Initialize[InputTask[A1]]](tree)
|
||||
wrapInput[A1](wrapInit[InputTask[A1]](c)(e, tree.pos).tree)
|
||||
}
|
||||
def wrapInput[T: c.WeakTypeTag](tree: Tree) = {
|
||||
val e = c.Expr[InputTask[T]](tree)
|
||||
val p = ParserInput.wrap[Task[T]](c)(ParserInput.inputParser(c)(e), tree.pos)
|
||||
wrapTask[T](c)(p, tree.pos).tree
|
||||
def wrapInput[A1: Type](tree: Tree) = {
|
||||
val e = c.Expr[InputTask[A1]](tree)
|
||||
val p = ParserInput.wrap[Task[A1]](c)(ParserInput.inputParser(c)(e), tree.pos)
|
||||
wrapTask[A1](c)(p, tree.pos).tree
|
||||
}
|
||||
|
||||
def expand(nme: String, tpe: Type, tree: Tree): Converted[c.type] = nme match {
|
||||
case WrapInitTaskName => Converted.Success(wrapInitTask(tree)(c.WeakTypeTag(tpe)))
|
||||
case WrapPreviousName => Converted.Success(wrapInitTask(tree)(c.WeakTypeTag(tpe)))
|
||||
case ParserInput.WrapInitName => Converted.Success(wrapInitParser(tree)(c.WeakTypeTag(tpe)))
|
||||
case WrapInitInputName => Converted.Success(wrapInitInput(tree)(c.WeakTypeTag(tpe)))
|
||||
case WrapInputName => Converted.Success(wrapInput(tree)(c.WeakTypeTag(tpe)))
|
||||
case WrapInitTaskName => Converted.Success(wrapInitTask(tree)(Type(tpe)))
|
||||
case WrapPreviousName => Converted.Success(wrapInitTask(tree)(Type(tpe)))
|
||||
case ParserInput.WrapInitName => Converted.Success(wrapInitParser(tree)(Type(tpe)))
|
||||
case WrapInitInputName => Converted.Success(wrapInitInput(tree)(Type(tpe)))
|
||||
case WrapInputName => Converted.Success(wrapInput(tree)(Type(tpe)))
|
||||
case _ => Converted.NotApplicable
|
||||
}
|
||||
val util = ContextUtil[c.type](c)
|
||||
util.transformWrappers(t, (nme, tpe, tree, original) => expand(nme, tpe, tree))
|
||||
}
|
||||
|
||||
private[this] def iParserMacro[M[_], T](c: blackbox.Context)(t: c.Expr[T])(
|
||||
f: c.Expr[T] => c.Expr[M[T]]
|
||||
)(implicit tt: c.WeakTypeTag[T], mt: c.WeakTypeTag[M[T]]): c.Expr[State => Parser[M[T]]] = {
|
||||
val inner: Transform[c.type, M] = (in: c.Tree) => f(c.Expr[T](in)).tree
|
||||
Instance.contImpl[T, M](c, ParserInstance, ParserConvert, MixedBuilder, LinterDSL.Empty)(
|
||||
private[A1his] def iParserMacro[M[_], T](c: blackbox.Context)(t: c.Expr[A1])(
|
||||
f: c.Expr[A1] => c.Expr[M[A1]]
|
||||
)(implicit tt: Type[A1], mt: Type[M[A1]]): c.Expr[State => Parser[M[A1]]] = {
|
||||
val inner: Transform[c.type, M] = (in: c.Tree) => f(c.Expr[A1](in)).tree
|
||||
Instance.contImpl[A1, M](c, ParserInstance, ParserConvert, MixedBuilder, LinterDSL.Empty)(
|
||||
Left(t),
|
||||
inner
|
||||
)
|
||||
}
|
||||
|
||||
private[this] def iTaskMacro[T: c.WeakTypeTag](
|
||||
private[A1his] def iTaskMacro[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[T]): c.Expr[Task[T]] =
|
||||
)(t: c.Expr[A1]): c.Expr[Task[A1]] =
|
||||
Instance
|
||||
.contImpl[T, Id](c, TaskInstance, TaskConvert, MixedBuilder, EmptyLinter)(
|
||||
.contImpl[A1, Id](c, TaskInstance, TaskConvert, MixedBuilder, EmptyLinter)(
|
||||
Left(t),
|
||||
Instance.idTransform
|
||||
)
|
||||
|
||||
private[this] def inputTaskDynMacro0[T: c.WeakTypeTag](
|
||||
private[A1his] def inputTaskDynMacro0[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[Initialize[Task[T]]]): c.Expr[Initialize[InputTask[T]]] = {
|
||||
)(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[InputTask[A1]]] = {
|
||||
import c.universe.{ Apply => ApplyTree, _ }
|
||||
import internal.decorators._
|
||||
|
||||
val tag = implicitly[c.WeakTypeTag[T]]
|
||||
val tag = implicitly[Type[A1]]
|
||||
val util = ContextUtil[c.type](c)
|
||||
val it = Ident(util.singleton(InputTask))
|
||||
val isParserWrapper = InitParserConvert.asPredicate(c)
|
||||
|
|
@ -545,7 +512,9 @@ object TaskMacro {
|
|||
val vd = util.freshValDef(tpe, qual.symbol.pos, functionSym) // val $x: <tpe>
|
||||
result = Some((qual, tpe, vd))
|
||||
val tree = util.refVal(original, vd) // $x
|
||||
tree.setPos(qual.pos) // position needs to be set so that wrapKey passes the position onto the wrapper
|
||||
tree.setPos(
|
||||
qual.pos
|
||||
) // position needs to be set so that wrapKey passes the position onto the wrapper
|
||||
assert(tree.tpe != null, "Null type: " + tree)
|
||||
tree.setType(tpe)
|
||||
tree
|
||||
|
|
@ -554,13 +523,13 @@ object TaskMacro {
|
|||
def inputTaskCreate(name: String, tpeA: Type, tpeB: Type, arg1: Tree, arg2: Tree) = {
|
||||
val typedApp = TypeApply(util.select(it, name), TypeTree(tpeA) :: TypeTree(tpeB) :: Nil)
|
||||
val app = ApplyTree(ApplyTree(typedApp, arg1 :: Nil), arg2 :: Nil)
|
||||
c.Expr[Initialize[InputTask[T]]](app)
|
||||
c.Expr[Initialize[InputTask[A1]]](app)
|
||||
}
|
||||
// Tree for InputTask.createFree[<tpe>](arg1)
|
||||
def inputTaskCreateFree(tpe: Type, arg: Tree) = {
|
||||
val typedApp = TypeApply(util.select(it, InputTaskCreateFreeName), TypeTree(tpe) :: Nil)
|
||||
val app = ApplyTree(typedApp, arg :: Nil)
|
||||
c.Expr[Initialize[InputTask[T]]](app)
|
||||
c.Expr[Initialize[InputTask[A1]]](app)
|
||||
}
|
||||
def expandTask[I: WeakTypeTag](dyn: Boolean, tx: Tree): c.Expr[Initialize[Task[I]]] =
|
||||
if (dyn)
|
||||
|
|
@ -570,7 +539,7 @@ object TaskMacro {
|
|||
def wrapTag[I: WeakTypeTag]: WeakTypeTag[Initialize[Task[I]]] = weakTypeTag
|
||||
|
||||
def sub(name: String, tpe: Type, qual: Tree, selection: Tree): Converted[c.type] = {
|
||||
val tag = c.WeakTypeTag[T](tpe)
|
||||
val tag = Type[A1](tpe)
|
||||
InitParserConvert(c)(name, qual)(tag) transform { tree =>
|
||||
subWrapper(tpe, tree, selection)
|
||||
}
|
||||
|
|
@ -582,28 +551,33 @@ object TaskMacro {
|
|||
val fCore = util.createFunction(param :: Nil, tx, functionSym)
|
||||
val bodyTpe = wrapTag(tag).tpe
|
||||
val fTpe = util.functionType(tpe :: Nil, bodyTpe)
|
||||
val fTag = c.WeakTypeTag[Any](fTpe) // don't know the actual type yet, so use Any
|
||||
val fTag = Type[Any](fTpe) // don't know the actual type yet, so use Any
|
||||
val fInit = expandTask(false, fCore)(fTag).tree
|
||||
inputTaskCreate(InputTaskCreateDynName, tpe, tag.tpe, p, fInit)
|
||||
case None =>
|
||||
val init = expandTask[T](true, tx).tree
|
||||
val init = expandTask[A1](true, tx).tree
|
||||
inputTaskCreateFree(tag.tpe, init)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
object PlainTaskMacro {
|
||||
def task[T](t: T): Task[T] = macro taskImpl[T]
|
||||
def taskImpl[T: c.WeakTypeTag](c: blackbox.Context)(t: c.Expr[T]): c.Expr[Task[T]] =
|
||||
Instance.contImpl[T, Id](c, TaskInstance, TaskConvert, MixedBuilder, OnlyTaskLinterDSL)(
|
||||
end TaskMacro
|
||||
|
||||
/*
|
||||
object PlainTaskMacro:
|
||||
def task[A1](t: T): Task[A1] = macro taskImpl[A1]
|
||||
def taskImpl[A1: Type](c: blackbox.Context)(t: c.Expr[A1]): c.Expr[Task[A1]] =
|
||||
Instance.contImpl[A1, Id](c, TaskInstance, TaskConvert, MixedBuilder, OnlyTaskLinterDSL)(
|
||||
Left(t),
|
||||
Instance.idTransform[c.type]
|
||||
)
|
||||
|
||||
def taskDyn[T](t: Task[T]): Task[T] = macro taskDynImpl[T]
|
||||
def taskDynImpl[T: c.WeakTypeTag](c: blackbox.Context)(t: c.Expr[Task[T]]): c.Expr[Task[T]] =
|
||||
Instance.contImpl[T, Id](c, TaskInstance, TaskConvert, MixedBuilder, OnlyTaskDynLinterDSL)(
|
||||
def taskDyn[A1](t: Task[A1]): Task[A1] = macro taskDynImpl[A1]
|
||||
def taskDynImpl[A1: Type](c: blackbox.Context)(t: c.Expr[Task[A1]]): c.Expr[Task[A1]] =
|
||||
Instance.contImpl[A1, Id](c, TaskInstance, TaskConvert, MixedBuilder, OnlyTaskDynLinterDSL)(
|
||||
Right(t),
|
||||
Instance.idTransform[c.type]
|
||||
)
|
||||
}
|
||||
|
||||
end PlainTaskMacro
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ package sbt
|
|||
|
||||
import scala.annotation.Annotation
|
||||
|
||||
/** An annotation to designate that the annotated entity
|
||||
/**
|
||||
* An annotation to designate that the annotated entity
|
||||
* should not be considered for additional sbt compiler checks.
|
||||
* These checks ensure that the DSL is predictable and prevents
|
||||
* users from doing dangerous things at the cost of a stricter
|
||||
|
|
|
|||
|
|
@ -112,8 +112,7 @@ object BuildSettingsInstances {
|
|||
implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = withScope(genSettingKey[A])
|
||||
implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = withScope(genTaskKey[A])
|
||||
|
||||
implicit def arbKey[A: Manifest](
|
||||
implicit
|
||||
implicit def arbKey[A: Manifest](implicit
|
||||
arbInputKey: Arbitrary[InputKey[A]],
|
||||
arbSettingKey: Arbitrary[SettingKey[A]],
|
||||
arbTaskKey: Arbitrary[TaskKey[A]],
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ object ScopedSpec extends Properties("Scoped") {
|
|||
}
|
||||
}
|
||||
|
||||
///
|
||||
// /
|
||||
|
||||
def settingKey[A](label: Label, manifest: Manifest[A], scope: Scope): SettingKey[A] = {
|
||||
val noJsonWriter = NoJsonWriter[A]()
|
||||
|
|
@ -101,7 +101,7 @@ object ScopedSpec extends Properties("Scoped") {
|
|||
AttributeKey[A](label.value)(manifest, jsonWriter)
|
||||
}
|
||||
|
||||
///
|
||||
// /
|
||||
|
||||
def expectEq(k1: Scoped, k2: Scoped): Prop =
|
||||
?=(k1, k2) && ?=(k2, k1) map eqLabels(k1, k2)
|
||||
|
|
|
|||
|
|
@ -87,9 +87,8 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax {
|
|||
}
|
||||
|
||||
property("Reference? / ConfigKey? / key == key in ThisScope.copy(..)") = {
|
||||
forAll(
|
||||
(r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: Key) =>
|
||||
expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k)
|
||||
forAll((r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: Key) =>
|
||||
expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ object Assign {
|
|||
)
|
||||
|
||||
val it1 = Def.inputTask {
|
||||
tsk.parsed //"as" //dummy.value.parsed
|
||||
tsk.parsed // "as" //dummy.value.parsed
|
||||
}
|
||||
val it2 = Def.inputTask {
|
||||
"lit"
|
||||
|
|
|
|||
|
|
@ -380,5 +380,5 @@ class TaskNegSpec extends funsuite.FixtureAnyFunSuite with fixture.TestDataFixtu
|
|||
""".stripMargin
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ object EvaluateTask {
|
|||
}
|
||||
|
||||
def logIncResult(result: Result[_], state: State, streams: Streams) = result match {
|
||||
case Inc(i) => logIncomplete(i, state, streams); case _ => ()
|
||||
case Result.Inc(i) => logIncomplete(i, state, streams); case _ => ()
|
||||
}
|
||||
|
||||
def logIncomplete(result: Incomplete, state: State, streams: Streams): Unit = {
|
||||
|
|
@ -623,8 +623,8 @@ object EvaluateTask {
|
|||
|
||||
def onResult[T, S](result: Result[T])(f: T => S): S =
|
||||
result match {
|
||||
case Value(v) => f(v)
|
||||
case Inc(inc) => throw inc
|
||||
case Result.Value(v) => f(v)
|
||||
case Result.Inc(inc) => throw inc
|
||||
}
|
||||
|
||||
// if the return type Seq[Setting[_]] is not explicitly given, scalac hangs
|
||||
|
|
|
|||
|
|
@ -742,8 +742,8 @@ object BuildServerProtocol {
|
|||
|
||||
private def bspCompileTask: Def.Initialize[Task[Int]] = Def.task {
|
||||
Keys.compile.result.value match {
|
||||
case Value(_) => StatusCode.Success
|
||||
case Inc(cause) =>
|
||||
case Result.Value(_) => StatusCode.Success
|
||||
case Result.Inc(cause) =>
|
||||
cause.getCause match {
|
||||
case _: CompileFailed => StatusCode.Error
|
||||
case _: InterruptedException => StatusCode.Cancelled
|
||||
|
|
|
|||
|
|
@ -7,13 +7,16 @@
|
|||
|
||||
package sbt
|
||||
|
||||
import sbt.internal.Action
|
||||
import sbt.internal.util.Types._
|
||||
import sbt.internal.util.{ ~>, AList, AttributeKey, AttributeMap }
|
||||
import ConcurrentRestrictions.{ Tag, TagMap, tagsKey }
|
||||
import sbt.internal.Action
|
||||
import sbt.util.Monad
|
||||
|
||||
/** Combines metadata `info` and a computation `work` to define a task. */
|
||||
final case class Task[A](info: Info[A], work: Action[A]) {
|
||||
/**
|
||||
* Combines metadata `info` and a computation `work` to define a task.
|
||||
*/
|
||||
final case class Task[A](info: Info[A], work: Action[A]):
|
||||
override def toString = info.name getOrElse ("Task(" + info + ")")
|
||||
override def hashCode = info.hashCode
|
||||
|
||||
|
|
@ -22,11 +25,31 @@ final case class Task[A](info: Info[A], work: Action[A]) {
|
|||
val tgs: TagMap = info.get(tagsKey).getOrElse(TagMap.empty)
|
||||
val value = tags.foldLeft(tgs)((acc, tag) => acc + tag)
|
||||
val nextInfo = info.set(tagsKey, value)
|
||||
copy(info = nextInfo)
|
||||
withInfo(info = nextInfo)
|
||||
}
|
||||
|
||||
def tags: TagMap = info get tagsKey getOrElse TagMap.empty
|
||||
}
|
||||
|
||||
private[sbt] def withInfo(info: Info[A]): Task[A] =
|
||||
Task(info = info, work = this.work)
|
||||
end Task
|
||||
|
||||
object Task:
|
||||
import sbt.std.TaskExtra.*
|
||||
|
||||
given taskMonad: Monad[Task] with
|
||||
type F[a] = Task[a]
|
||||
override def pure[A1](a: () => A1): Task[A1] = toTask(a)
|
||||
|
||||
override def ap[A1, A2](ff: Task[A1 => A2])(in: Task[A1]): Task[A2] =
|
||||
multT2Task((in, ff)).map { case (x, f) =>
|
||||
f(x)
|
||||
}
|
||||
|
||||
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]])
|
||||
end Task
|
||||
|
||||
/**
|
||||
* Used to provide information about a task, such as the name, description, and tags for controlling
|
||||
|
|
@ -52,8 +75,9 @@ final case class Info[T](
|
|||
|
||||
override def toString = if (attributes.isEmpty) "_" else attributes.toString
|
||||
}
|
||||
object Info {
|
||||
|
||||
object Info:
|
||||
val Name = AttributeKey[String]("name")
|
||||
val Description = AttributeKey[String]("description")
|
||||
val defaultAttributeMap = const(AttributeMap.empty)
|
||||
}
|
||||
end Info
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ trait TaskExtra extends TaskExtra0 {
|
|||
final implicit def upcastTask[A >: B, B](t: Task[B]): Task[A] = t map { x =>
|
||||
x: A
|
||||
}
|
||||
|
||||
final implicit def toTasks[S](in: Seq[() => S]): Seq[Task[S]] = in.map(toTask)
|
||||
final implicit def iterableTask[S](in: Seq[S]): ForkTask[S, Seq] = new ForkTask[S, Seq] {
|
||||
def fork[T](f: S => T): Seq[Task[T]] = in.map(x => task(f(x)))
|
||||
|
|
@ -271,6 +272,7 @@ trait TaskExtra extends TaskExtra0 {
|
|||
(p run pio).exitValue()
|
||||
}
|
||||
}
|
||||
|
||||
object TaskExtra extends TaskExtra {
|
||||
def processIO(s: TaskStreams[_]): ProcessIO = {
|
||||
def transfer(id: String) = (in: InputStream) => BasicIO.transferFully(in, s.binary(id))
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ private[sbt] final class Execute[F[_] <: AnyRef](
|
|||
|
||||
private[this] val forward = idMap[F[Any], IDSet[F[Any]]]
|
||||
private[this] val reverse = idMap[F[Any], Iterable[F[Any]]]
|
||||
private[this] val callers = pMap[F, Compose[IDSet, F]#Apply]
|
||||
private[this] val callers = pMap[F, Compose[IDSet, F]]
|
||||
private[this] val state = idMap[F[Any], State]
|
||||
private[this] val viewCache = pMap[F, Node[F, *]]
|
||||
private[this] val results = pMap[F, Result]
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@
|
|||
|
||||
package sbt.util
|
||||
|
||||
import scala.reflect.Manifest
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
import sjsonnew.{ BasicJsonProtocol, Builder, deserializationError, JsonFormat, Unbuilder }
|
||||
|
||||
object StampedFormat extends BasicJsonProtocol {
|
||||
|
||||
def apply[T](format: JsonFormat[T])(implicit mf: Manifest[JsonFormat[T]]): JsonFormat[T] = {
|
||||
def apply[T](format: JsonFormat[T])(implicit mf: ClassTag[JsonFormat[T]]): JsonFormat[T] = {
|
||||
withStamp(stamp(format))(format)
|
||||
}
|
||||
|
||||
|
|
@ -46,9 +46,9 @@ object StampedFormat extends BasicJsonProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
private def stamp[T](format: JsonFormat[T])(implicit mf: Manifest[JsonFormat[T]]): Int =
|
||||
private def stamp[T](format: JsonFormat[T])(implicit mf: ClassTag[JsonFormat[T]]): Int =
|
||||
typeHash(mf)
|
||||
|
||||
private def typeHash[T](implicit mf: Manifest[T]) = mf.toString.hashCode
|
||||
private def typeHash[T](implicit mf: ClassTag[T]) = mf.toString.hashCode
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,29 +64,87 @@ object AList:
|
|||
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(())
|
||||
): 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(())
|
||||
): F2[Unit] = summon[Applicative[F2]].pure(() => ())
|
||||
override def foldr[F1[_], A2](value: Unit, init: A2)(
|
||||
f: [a] => (F1[a], A2) => A2
|
||||
): A2 = init
|
||||
|
||||
def single[A1]: AList[[F[_]] =>> F[A1]] =
|
||||
new AList[[F[_]] =>> F[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 Single[A1] = AList[[F[_]] =>> F[A1]]
|
||||
|
||||
def tuple2[A1, A2]: AList[[F[_]] =>> Tuple.Map[(A1, A2), F]] = tuple[(A1, A2)]
|
||||
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]]:
|
||||
|
|
@ -104,7 +162,8 @@ object AList:
|
|||
): 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 _: 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)
|
||||
|
|
@ -117,7 +176,7 @@ object AList:
|
|||
): 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 _: 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]) =>
|
||||
|
|
@ -142,7 +201,7 @@ object AList:
|
|||
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 Nil => ap.pure(() => g(Nil))
|
||||
case x :: xs =>
|
||||
val h = (ts: List[A]) => (t: A) => g(t :: ts)
|
||||
ap.ap(loop(xs, h))(x)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
package sbt.internal.util
|
||||
|
||||
import Types._
|
||||
import scala.reflect.Manifest
|
||||
import scala.reflect.ClassTag
|
||||
import sbt.util.OptJsonWriter
|
||||
|
||||
// T must be invariant to work properly.
|
||||
|
|
@ -19,10 +19,11 @@ import sbt.util.OptJsonWriter
|
|||
* A key in an [[AttributeMap]] that constrains its associated value to be of type `T`. The key is
|
||||
* uniquely defined by its `label` and type `T`, represented at runtime by `manifest`.
|
||||
*/
|
||||
sealed trait AttributeKey[T] {
|
||||
sealed trait AttributeKey[A]:
|
||||
|
||||
/** The runtime evidence for `T`. */
|
||||
def manifest: Manifest[T]
|
||||
// def manifest: Manifest[A]
|
||||
def classTag: ClassTag[A]
|
||||
|
||||
/** The label is the identifier for the key and is camelCase by convention. */
|
||||
def label: String
|
||||
|
|
@ -47,46 +48,46 @@ sealed trait AttributeKey[T] {
|
|||
/** Identifies the relative importance of a key among other keys. */
|
||||
def rank: Int
|
||||
|
||||
def optJsonWriter: OptJsonWriter[T]
|
||||
def optJsonWriter: OptJsonWriter[A]
|
||||
|
||||
}
|
||||
end AttributeKey
|
||||
|
||||
private[sbt] abstract class SharedAttributeKey[T] extends AttributeKey[T] {
|
||||
override final def toString = label
|
||||
override final def hashCode = label.hashCode
|
||||
override final def equals(o: Any) =
|
||||
(this eq o.asInstanceOf[AnyRef]) || (o match {
|
||||
case a: SharedAttributeKey[t] => a.label == this.label && a.manifest == this.manifest
|
||||
case a: SharedAttributeKey[t] => a.label == this.label && a.classTag == this.classTag
|
||||
case _ => false
|
||||
})
|
||||
final def isLocal: Boolean = false
|
||||
}
|
||||
|
||||
object AttributeKey {
|
||||
def apply[T: Manifest: OptJsonWriter](name: String): AttributeKey[T] =
|
||||
def apply[T: ClassTag: OptJsonWriter](name: String): AttributeKey[T] =
|
||||
make(name, None, Nil, Int.MaxValue)
|
||||
|
||||
def apply[T: Manifest: OptJsonWriter](name: String, rank: Int): AttributeKey[T] =
|
||||
def apply[T: ClassTag: OptJsonWriter](name: String, rank: Int): AttributeKey[T] =
|
||||
make(name, None, Nil, rank)
|
||||
|
||||
def apply[T: Manifest: OptJsonWriter](name: String, description: String): AttributeKey[T] =
|
||||
def apply[T: ClassTag: OptJsonWriter](name: String, description: String): AttributeKey[T] =
|
||||
apply(name, description, Nil)
|
||||
|
||||
def apply[T: Manifest: OptJsonWriter](
|
||||
def apply[T: ClassTag: OptJsonWriter](
|
||||
name: String,
|
||||
description: String,
|
||||
rank: Int
|
||||
): AttributeKey[T] =
|
||||
apply(name, description, Nil, rank)
|
||||
|
||||
def apply[T: Manifest: OptJsonWriter](
|
||||
def apply[T: ClassTag: OptJsonWriter](
|
||||
name: String,
|
||||
description: String,
|
||||
extend: Seq[AttributeKey[_]]
|
||||
): AttributeKey[T] =
|
||||
apply(name, description, extend, Int.MaxValue)
|
||||
|
||||
def apply[T: Manifest: OptJsonWriter](
|
||||
def apply[T: ClassTag: OptJsonWriter](
|
||||
name: String,
|
||||
description: String,
|
||||
extend: Seq[AttributeKey[_]],
|
||||
|
|
@ -95,21 +96,21 @@ object AttributeKey {
|
|||
make(name, Some(description), extend, rank)
|
||||
|
||||
private[sbt] def copyWithRank[T](a: AttributeKey[T], rank: Int): AttributeKey[T] =
|
||||
make(a.label, a.description, a.extend, rank)(a.manifest, a.optJsonWriter)
|
||||
make(a.label, a.description, a.extend, rank)(a.classTag, a.optJsonWriter)
|
||||
|
||||
private[this] def make[T](
|
||||
name: String,
|
||||
description0: Option[String],
|
||||
extend0: Seq[AttributeKey[_]],
|
||||
rank0: Int
|
||||
)(implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] =
|
||||
)(implicit mf: ClassTag[T], ojw: OptJsonWriter[T]): AttributeKey[T] =
|
||||
new SharedAttributeKey[T] {
|
||||
require(
|
||||
name.headOption.exists(_.isLower),
|
||||
s"A named attribute key must start with a lowercase letter: $name"
|
||||
)
|
||||
|
||||
def manifest = mf
|
||||
def classTag = mf
|
||||
val label = Util.hyphenToCamel(name)
|
||||
def description = description0
|
||||
def extend = extend0
|
||||
|
|
@ -117,9 +118,9 @@ object AttributeKey {
|
|||
def optJsonWriter = ojw
|
||||
}
|
||||
|
||||
private[sbt] def local[T](implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] =
|
||||
private[sbt] def local[T](implicit mf: ClassTag[T], ojw: OptJsonWriter[T]): AttributeKey[T] =
|
||||
new AttributeKey[T] {
|
||||
def manifest = mf
|
||||
def classTag = mf
|
||||
def label = LocalLabel
|
||||
def description = None
|
||||
def extend = Nil
|
||||
|
|
|
|||
|
|
@ -105,14 +105,19 @@ trait Init[ScopeType]:
|
|||
def update[A1](key: ScopedKey[A1])(f: A1 => A1): Setting[A1] =
|
||||
setting[A1](key, map(key)(f), NoPosition)
|
||||
|
||||
def bind[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] =
|
||||
Apply[[F[_]] =>> F[A1], A2](f, in, AList.single[A1])
|
||||
|
||||
def app[K[L[x]], T](inputs: K[Initialize])(f: K[Id] => T)(implicit
|
||||
def app[K[L[x]], A2](inputs: K[Initialize])(f: K[Id] => A2)(implicit
|
||||
alist: AList[K]
|
||||
): Initialize[T] = Apply[K, T](f, inputs, alist)
|
||||
): Initialize[A2] = Apply[K, A2](f, inputs, alist)
|
||||
|
||||
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])
|
||||
|
||||
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])
|
||||
|
|
@ -657,8 +662,10 @@ trait Init[ScopeType]:
|
|||
|
||||
def evaluate(map: Settings[ScopeType]): A1
|
||||
def zip[A2](o: Initialize[A2]): Initialize[(A1, A2)] = zipTupled(o)(idFun)
|
||||
|
||||
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])
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,12 @@ trait TypeFunctions:
|
|||
type ConstK[A] = [F[_]] =>> A
|
||||
*/
|
||||
|
||||
sealed trait Compose[A[_], B[_]] { type Apply[T] = A[B[T]] }
|
||||
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]
|
||||
|
|
@ -39,12 +44,13 @@ trait TypeFunctions:
|
|||
|
||||
final def idK[F[_]]: [a] => F[a] => F[a] = [a] =>
|
||||
(fa: F[a]) => fa // .setToString("TypeFunctions.idK")
|
||||
/*
|
||||
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:
|
||||
// λ[(M ∙ G)#l ~> (N ∙ G)#l](f(_))
|
||||
|
||||
inline def nestCon[F1[_], F2[_], F3[_]](
|
||||
f: [a] => F1[a] => F2[a]
|
||||
): [a] => Compose[F1, F3][a] => Compose[F2, F3][a] =
|
||||
f.asInstanceOf[[a] => Compose[F1, F3][a] => Compose[F2, F3][a]]
|
||||
|
||||
/*
|
||||
type Endo[T] = T => T
|
||||
type ~>|[A[_], B[_]] = A ~> Compose[Option, B]#Apply
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -7,14 +7,27 @@
|
|||
|
||||
package sbt.util
|
||||
|
||||
trait Applicative[F[_]] extends Apply[F]:
|
||||
def pure[A](x: A): F[A]
|
||||
import sbt.internal.util.Types.Compose
|
||||
|
||||
override def map[A, B](fa: F[A])(f: A => B): F[B] =
|
||||
ap(pure(f))(fa)
|
||||
trait Applicative[F[_]] extends Apply[F]:
|
||||
def pure[A1](x: () => A1): F[A1]
|
||||
|
||||
override def map[A1, A2](fa: F[A1])(f: A1 => A2): F[A2] =
|
||||
ap(pure(() => f))(fa)
|
||||
end Applicative
|
||||
|
||||
object Applicative:
|
||||
given Applicative[Option] = OptionInstances.optionMonad
|
||||
given Applicative[List] = ListInstances.listMonad
|
||||
|
||||
given [F1[_], F2[_]](using Applicative[F1], Applicative[F2]): Applicative[Compose[F1, F2]] with
|
||||
type F[x] = F1[F2[x]]
|
||||
val F1 = summon[Applicative[F1]]
|
||||
val F2 = summon[Applicative[F2]]
|
||||
override def pure[A1](x: () => A1): F1[F2[A1]] = F1.pure(() => F2.pure(x))
|
||||
override def ap[A1, A2](f1f2f: Compose[F1, F2][A1 => A2])(
|
||||
f1f2a: Compose[F1, F2][A1]
|
||||
): F1[F2[A2]] =
|
||||
F1.ap(F1.map(f1f2f) { (f2f: F2[A1 => A2]) => (f2a: F2[A1]) => F2.ap(f2f)(f2a) })(f1f2a)
|
||||
|
||||
end Applicative
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@
|
|||
package sbt.util
|
||||
|
||||
trait Apply[F[_]] extends Functor[F]:
|
||||
def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]
|
||||
def ap[A1, A2](ff: F[A1 => A2])(fa: F[A1]): F[A2]
|
||||
|
||||
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] =
|
||||
ap(map(fa)(a => (b: B) => (a, b)))(fb)
|
||||
def product[A1, A2](fa: F[A1], fb: F[A2]): F[(A1, A2)] =
|
||||
ap(map(fa)(a => (b: A2) => (a, b)))(fb)
|
||||
end Apply
|
||||
|
||||
object Apply:
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import scala.annotation.implicitNotFound
|
|||
|
||||
@implicitNotFound("Could not find an instance of FlatMap for ${F}")
|
||||
trait FlatMap[F[_]] extends Apply[F]:
|
||||
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
|
||||
def flatMap[A1, A2](fa: F[A1])(f: A1 => F[A2]): F[A2]
|
||||
|
||||
def flatten[A](ffa: F[F[A]]): F[A] =
|
||||
def flatten[A1](ffa: F[F[A1]]): F[A1] =
|
||||
flatMap(ffa)(fa => fa)
|
||||
end FlatMap
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
package sbt.util
|
||||
|
||||
trait Functor[F[_]]:
|
||||
def map[A, B](fa: F[A])(f: A => B): F[B]
|
||||
def map[A1, A2](fa: F[A1])(f: A1 => A2): F[A2]
|
||||
end Functor
|
||||
|
||||
object Functor:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ private[sbt] object ListInstances:
|
|||
lazy val listMonad: Monad[List] =
|
||||
new Monad[List]:
|
||||
type F[a] = List[a]
|
||||
def pure[A](x: A): List[A] = List(x)
|
||||
def pure[A1](x: () => A1): List[A1] = List(x())
|
||||
def ap[A, B](ff: List[A => B])(fa: List[A]): List[B] =
|
||||
for
|
||||
f <- ff
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ private[sbt] object OptionInstances:
|
|||
new Monad[Option]:
|
||||
type F[a] = Option[a]
|
||||
|
||||
def pure[A](x: A): Option[A] = Some(x)
|
||||
def pure[A](x: () => A): Option[A] = Some(x())
|
||||
def ap[A, B](ff: Option[A => B])(fa: Option[A]): Option[B] =
|
||||
if ff.isDefined && fa.isDefined then Some(ff.get(fa.get))
|
||||
else None
|
||||
|
|
|
|||
Loading…
Reference in New Issue