This commit is contained in:
Eugene Yokota 2022-05-14 23:52:17 -04:00
parent 0a38e296ad
commit 340721c4a1
44 changed files with 1207 additions and 973 deletions

1
.gitignore vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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]
)
}
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -380,5 +380,5 @@ class TaskNegSpec extends funsuite.FixtureAnyFunSuite with fixture.TestDataFixtu
""".stripMargin
}
}
*/
*/
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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