mirror of https://github.com/sbt/sbt.git
Starting input task
This commit is contained in:
parent
b715917d95
commit
f3dd2dff36
|
|
@ -24,12 +24,26 @@ trait Cont:
|
|||
*/
|
||||
def contMapN[A: Type, F[_], Effect[_]: Type](
|
||||
tree: Expr[A],
|
||||
instanceExpr: Expr[Applicative[F]]
|
||||
)(using
|
||||
iftpe: Type[F],
|
||||
eatpe: Type[Effect[A]],
|
||||
): Expr[F[Effect[A]]] =
|
||||
contMapN[A, F, Effect](tree, instanceExpr, conv.idTransform)
|
||||
|
||||
/**
|
||||
* Implementation of a macro that provides a direct syntax for applicative functors. It is
|
||||
* intended to be used in conjunction with another macro that conditions the inputs.
|
||||
*/
|
||||
def contMapN[A: Type, F[_], Effect[_]: Type](
|
||||
tree: Expr[A],
|
||||
instanceExpr: Expr[Applicative[F]],
|
||||
inner: conv.TermTransform[Effect]
|
||||
)(using
|
||||
iftpe: Type[F],
|
||||
eatpe: Type[Effect[A]],
|
||||
): Expr[F[Effect[A]]] =
|
||||
contImpl[A, F, Effect](Left(tree), inner)
|
||||
contImpl[A, F, Effect](Left(tree), instanceExpr, inner)
|
||||
|
||||
/**
|
||||
* Implementation of a macro that provides a direct syntax for applicative functors. It is
|
||||
|
|
@ -37,16 +51,38 @@ trait Cont:
|
|||
*/
|
||||
def contFlatMap[A: Type, F[_], Effect[_]: Type](
|
||||
tree: Expr[F[A]],
|
||||
instanceExpr: Expr[Applicative[F]],
|
||||
)(using
|
||||
iftpe: Type[F],
|
||||
eatpe: Type[Effect[A]],
|
||||
): Expr[F[Effect[A]]] =
|
||||
contFlatMap[A, F, Effect](tree, instanceExpr, conv.idTransform)
|
||||
|
||||
/**
|
||||
* Implementation of a macro that provides a direct syntax for applicative functors. It is
|
||||
* intended to be used in conjunction with another macro that conditions the inputs.
|
||||
*/
|
||||
def contFlatMap[A: Type, F[_], Effect[_]: Type](
|
||||
tree: Expr[F[A]],
|
||||
instanceExpr: Expr[Applicative[F]],
|
||||
inner: conv.TermTransform[Effect]
|
||||
)(using
|
||||
iftpe: Type[F],
|
||||
eatpe: Type[Effect[A]],
|
||||
): Expr[F[Effect[A]]] =
|
||||
contImpl[A, F, Effect](Right(tree), inner)
|
||||
contImpl[A, F, Effect](Right(tree), instanceExpr, inner)
|
||||
|
||||
def summonAppExpr[F[_]: Type]: Expr[Applicative[F]] =
|
||||
import conv.qctx
|
||||
import qctx.reflect.*
|
||||
given qctx.type = qctx
|
||||
Expr
|
||||
.summon[Applicative[F]]
|
||||
.getOrElse(sys.error(s"Applicative[F] not found for ${TypeRepr.of[F].typeSymbol}"))
|
||||
|
||||
/**
|
||||
* Implementation of a macro that provides a direct syntax for applicative functors and monads.
|
||||
* It is intended to be used in conjunction with another macro that conditions the inputs.
|
||||
* It is intended to bcke used in conjunction with another macro that conditions the inputs.
|
||||
*
|
||||
* This method processes the Term `t` to find inputs of the form `wrap[A]( input )` This form is
|
||||
* typically constructed by another macro that pretends to be able to get a value of type `A`
|
||||
|
|
@ -83,6 +119,7 @@ trait Cont:
|
|||
*/
|
||||
def contImpl[A: Type, F[_], Effect[_]: Type](
|
||||
eitherTree: Either[Expr[A], Expr[F[A]]],
|
||||
instanceExpr: Expr[Applicative[F]],
|
||||
inner: conv.TermTransform[Effect]
|
||||
)(using
|
||||
iftpe: Type[F],
|
||||
|
|
@ -98,11 +135,6 @@ trait Cont:
|
|||
case Left(l) => (l, TypeRepr.of[Effect[A]])
|
||||
case Right(r) => (r, faTpe)
|
||||
|
||||
// we can extract i out of i.type
|
||||
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
|
||||
|
|
|
|||
|
|
@ -62,5 +62,5 @@ trait ContextUtil[C <: Quotes & scala.Singleton](val qctx: C):
|
|||
def apply(in: Term): Term
|
||||
end TermTransform
|
||||
|
||||
def idTransform: TermTransform[Id] = in => in
|
||||
def idTransform[F[_]]: TermTransform[F] = in => in
|
||||
end ContextUtil
|
||||
|
|
|
|||
|
|
@ -39,12 +39,19 @@ trait Convert[C <: Quotes & Singleton](override val qctx: C) extends ContextUtil
|
|||
subWrapper: (String, TypeRepr, Term, Term) => Converted,
|
||||
owner: Symbol,
|
||||
): Term =
|
||||
object ApplySelectOrIdent:
|
||||
def unapply(tree: Term): Option[(String, TypeTree, Term)] = tree match
|
||||
case Apply(TypeApply(Select(_, nme), targ :: Nil), qual :: Nil) => Some((nme, targ, qual))
|
||||
case Apply(TypeApply(Ident(nme), targ :: Nil), qual :: Nil) => Some((nme, targ, qual))
|
||||
case _ => None
|
||||
end ApplySelectOrIdent
|
||||
|
||||
// the main tree transformer that replaces calls to InputWrapper.wrap(x) with
|
||||
// plain Idents that reference the actual input value
|
||||
object appTransformer extends TreeMap:
|
||||
override def transformTerm(tree: Term)(owner: Symbol): Term =
|
||||
tree match
|
||||
case Apply(TypeApply(Select(_, nme), targ :: Nil), qual :: Nil) =>
|
||||
case ApplySelectOrIdent(nme, targ, qual) =>
|
||||
subWrapper(nme, targ.tpe, qual, tree) match
|
||||
case Converted.Success(tree, finalTransform) =>
|
||||
finalTransform(tree)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ object ContTestMacro:
|
|||
object ContSyntax extends Cont
|
||||
import ContSyntax.*
|
||||
val convert1: Convert[qctx.type] = new InputInitConvert(qctx)
|
||||
convert1.contMapN[A, List, Id](expr, convert1.idTransform)
|
||||
convert1.contMapN[A, List, Id](expr, convert1.summonAppExpr[List], convert1.idTransform)
|
||||
|
||||
end ContTestMacro
|
||||
|
|
|
|||
|
|
@ -210,38 +210,33 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits:
|
|||
/** Lifts the result of a setting initialization into a Task. */
|
||||
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)
|
||||
inline def toSParser[A1](p: Parser[A1]): State => Parser[A1] = const(p)
|
||||
def toISParser[A1](p: Initialize[Parser[A1]]): Initialize[State => Parser[A1]] =
|
||||
p.apply[State => Parser[A1]](toSParser(_))
|
||||
def toIParser[A1](p: Initialize[InputTask[A1]]): Initialize[State => Parser[Task[A1]]] =
|
||||
p(_.parser)
|
||||
|
||||
import std.SettingMacro.{
|
||||
// settingDynMacroImpl,
|
||||
settingMacroImpl
|
||||
}
|
||||
import std.TaskMacro.{
|
||||
// inputTaskDynMacroImpl,
|
||||
// inputTaskMacroImpl,
|
||||
taskDynMacroImpl,
|
||||
// taskIfMacroImpl,
|
||||
taskMacroImpl,
|
||||
}
|
||||
import std._
|
||||
import std.*
|
||||
|
||||
import language.experimental.macros
|
||||
|
||||
inline def task[A1](inline a1: A1): Def.Initialize[Task[A1]] =
|
||||
${ taskMacroImpl[A1]('a1) }
|
||||
${ TaskMacro.taskMacroImpl[A1]('a1) }
|
||||
|
||||
inline def taskDyn[A1](a1: Def.Initialize[Task[A1]]): Def.Initialize[Task[A1]] =
|
||||
${ taskDynMacroImpl[A1]('a1) }
|
||||
${ TaskMacro.taskDynMacroImpl[A1]('a1) }
|
||||
|
||||
inline def setting[A1](inline a: A1): Def.Initialize[A1] = ${ settingMacroImpl[A1]('a) }
|
||||
|
||||
// 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]
|
||||
// }
|
||||
|
||||
inline def inputTask[A1](inline a: A1): Def.Initialize[InputTask[A1]] =
|
||||
${ TaskMacro.inputTaskMacroImpl[A1]('a) }
|
||||
|
||||
// def taskIf[T](a: T): Def.Initialize[Task[T]] = macro taskIfMacroImpl[T]
|
||||
|
||||
private[sbt] def selectITask[A1, A2](
|
||||
|
|
@ -310,14 +305,14 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits:
|
|||
|
||||
// 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] = ???
|
||||
// result of type A1, previously implemented using ParserInput.parsedMacroImpl[A1].
|
||||
|
||||
// implicit def parserInitStateToInput[T](
|
||||
// @deprecated("unused", "") p: Initialize[State => Parser[T]]
|
||||
// ): ParserInput[T] = ???
|
||||
extension [A1](in: Initialize[Parser[A1]])
|
||||
inline def parsed: A1 = ParserInput.wrapInit[A1](Def.toISParser(in))
|
||||
|
||||
extension [A1](in: Initialize[State => Parser[A1]])
|
||||
@targetName("parsedISPA1")
|
||||
inline def parsed: A1 = ParserInput.wrapInit[A1](in)
|
||||
|
||||
inline def settingKey[A1](inline description: String): SettingKey[A1] =
|
||||
${ std.KeyMacro.settingKeyImpl[A1]('description) }
|
||||
|
|
@ -382,18 +377,19 @@ 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 {
|
||||
trait TaskMacroExtra:
|
||||
import sbt.std.ParserInput
|
||||
// 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 parserToInput[T](@deprecated("unused", "") in: Parser[T]): std.ParserInput[T] = ???
|
||||
extension [A1](in: Parser[A1])
|
||||
inline def parsed: A1 = ParserInput.`parser_\u2603\u2603`[A1](Def.toSParser(in))
|
||||
|
||||
// implicit def stateParserToInput[T](
|
||||
// @deprecated("unused", "") in: State => Parser[T]
|
||||
// ): std.ParserInput[T] = ???
|
||||
}
|
||||
extension [A1](in: State => Parser[A1])
|
||||
inline def parsed: A1 = ParserInput.`parser_\u2603\u2603`[A1](in)
|
||||
end TaskMacroExtra
|
||||
|
||||
sealed trait InitializeImplicits0 { self: Def.type =>
|
||||
implicit def initOps[T](x: Def.Initialize[T]): Def.InitOps[T] = new Def.InitOps(x)
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ final class InputTask[A1] private (val parser: State => Parser[Task[A1]]):
|
|||
)
|
||||
end InputTask
|
||||
|
||||
/*
|
||||
object InputTask {
|
||||
object InputTask:
|
||||
/*
|
||||
implicit class InitializeInput[T](i: Initialize[InputTask[T]]) {
|
||||
def partialInput(in: String): Initialize[InputTask[T]] = i(_ partialInput in)
|
||||
def fullInput(in: String): Initialize[InputTask[T]] = i(_ fullInput in)
|
||||
|
|
@ -61,9 +61,11 @@ object InputTask {
|
|||
implicit def inputTaskInitParsed[T](
|
||||
@deprecated("unused", "") in: Initialize[InputTask[T]]
|
||||
): std.ParserInputTask[T] = ???
|
||||
*/
|
||||
|
||||
def make[T](p: State => Parser[Task[T]]): InputTask[T] = new InputTask[T](p)
|
||||
def make[A1](p: State => Parser[Task[A1]]): InputTask[A1] = new InputTask[A1](p)
|
||||
|
||||
/*
|
||||
def static[T](p: Parser[Task[T]]): InputTask[T] = free(_ => p)
|
||||
|
||||
def static[I, T](p: Parser[I])(c: I => Task[T]): InputTask[T] = static(p map c)
|
||||
|
|
@ -89,10 +91,10 @@ 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]] =
|
||||
|
|
@ -124,10 +126,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]]
|
||||
|
||||
|
|
@ -173,5 +175,5 @@ object InputTask {
|
|||
}
|
||||
f(task)
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
end InputTask
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ package std
|
|||
import sbt.internal.util.appmacro.{ Convert, ContextUtil }
|
||||
import sbt.internal.util.complete.Parser
|
||||
import Def.Initialize
|
||||
import sbt.util.Applicative
|
||||
import sbt.internal.util.Types.Compose
|
||||
import scala.quoted.*
|
||||
|
||||
class InputInitConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
||||
|
|
@ -25,6 +27,9 @@ class InputInitConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
|||
case _ => Converted.NotApplicable()
|
||||
|
||||
private def initTaskErrorMessage = "Internal sbt error: initialize+task wrapper not split"
|
||||
|
||||
def appExpr: Expr[Applicative[Initialize]] =
|
||||
'{ InitializeInstance.initializeMonad }
|
||||
end InputInitConvert
|
||||
|
||||
/** Converts an input `Term` of type `Parser[A]` or `State => Parser[A]` into a `Term` of type `State => Parser[A]`. */
|
||||
|
|
@ -40,6 +45,9 @@ class ParserConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
|||
case _ => Converted.NotApplicable()
|
||||
|
||||
private def initParserErrorMessage = "Internal sbt error: initialize+parser wrapper not split"
|
||||
|
||||
def appExpr: Expr[Applicative[ParserInstance.F1]] =
|
||||
'{ ParserInstance.parserFunApplicative }
|
||||
end ParserConvert
|
||||
|
||||
/** Convert instance for plain `Task`s not within the settings system. */
|
||||
|
|
@ -50,6 +58,9 @@ class TaskConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
|||
override def convert[A: Type](nme: String, in: Term): Converted =
|
||||
if nme == InputWrapper.WrapTaskName then Converted.success(in)
|
||||
else Converted.NotApplicable()
|
||||
|
||||
def appExpr[Expr[Monad[Task]]] =
|
||||
'{ Task.taskMonad }
|
||||
end TaskConvert
|
||||
|
||||
/**
|
||||
|
|
@ -83,6 +94,8 @@ class FullConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
|||
}
|
||||
Converted.success(t.asTerm)
|
||||
|
||||
def appExpr: Expr[Applicative[Compose[Initialize, Task]]] =
|
||||
'{ FullInstance.initializeTaskMonad }
|
||||
end FullConvert
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ object InputWrapper:
|
|||
private[this] def implDetailError =
|
||||
sys.error("This method is an implementation detail and should not be referenced.")
|
||||
|
||||
inline def wrapTask[A](in: Any): A = `wrapTask_\u2603\u2603`[A](in)
|
||||
inline def wrapInit[A](in: Any): A = `wrapInit_\u2603\u2603`[A](in)
|
||||
|
||||
/*
|
||||
private[std] def wrapInitInputTask[T: c.WeakTypeTag](using qctx: Quotes)(
|
||||
ts: c.Expr[Any],
|
||||
|
|
@ -189,12 +192,6 @@ sealed abstract class MacroValue[A1] {
|
|||
def value: A1 = macro InputWrapper.valueMacroImpl[A1]
|
||||
}
|
||||
|
||||
sealed abstract class ParserInput[T] {
|
||||
@compileTimeOnly(
|
||||
"`parsed` can only be used within an input task macro, such as := or Def.inputTask."
|
||||
)
|
||||
def parsed: T = macro ParserInput.parsedMacroImpl[T]
|
||||
}
|
||||
sealed abstract class InputEvaluated[T] {
|
||||
@compileTimeOnly(
|
||||
"`evaluated` can only be used within an input task macro, such as := or Def.inputTask."
|
||||
|
|
@ -239,16 +236,11 @@ 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](
|
||||
using qctx: Quotes
|
||||
)(ts: c.Expr[Any], pos: c.Position): c.Expr[T] =
|
||||
InputWrapper.wrapImpl[T, ParserInput.type](c, ParserInput, WrapName)(ts, pos)
|
||||
private[std] def wrapInit[T: c.WeakTypeTag](
|
||||
using qctx: Quotes
|
||||
)(ts: c.Expr[Any], pos: c.Position): c.Expr[T] =
|
||||
InputWrapper.wrapImpl[T, ParserInput.type](c, ParserInput, WrapInitName)(ts, pos)
|
||||
|
||||
inline def wrap[A1](in: Any): A1 = `parser_\u2603\u2603`[A1](in)
|
||||
inline def wrapInit[A1](in: Any): A1 = `initParser_\u2603\u2603`[A1](in)
|
||||
|
||||
/*
|
||||
private[std] def inputParser[T: c.WeakTypeTag](
|
||||
using qctx: Quotes
|
||||
)(t: c.Expr[InputTask[T]]): c.Expr[State => Parser[Task[T]]] =
|
||||
|
|
|
|||
|
|
@ -29,10 +29,12 @@ 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]]]
|
||||
val F1F2: Applicative[Compose[Initialize, Task]] =
|
||||
summon[Applicative[Compose[Initialize, Task]]]
|
||||
end ComposeInstance
|
||||
|
||||
object ParserInstance:
|
||||
type F1[x] = State => Parser[x]
|
||||
// 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) }
|
||||
|
|
@ -40,7 +42,7 @@ object ParserInstance:
|
|||
// def map[S, T](f: S => T, v: M[S]) = s => v(s).map(f)
|
||||
// }
|
||||
|
||||
given Applicative[[a] =>> State => Parser[a]] with
|
||||
given parserFunApplicative: Applicative[F1] 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] =
|
||||
|
|
@ -60,7 +62,7 @@ object FullInstance:
|
|||
|
||||
given Monad[Initialize] = InitializeInstance.initializeMonad
|
||||
val F1F2: Applicative[Compose[Initialize, Task]] = ComposeInstance.F1F2
|
||||
given Monad[Compose[Initialize, Task]] with
|
||||
given initializeTaskMonad: 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]])(
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import sbt.internal.util.appmacro.{
|
|||
Convert,
|
||||
// LinterDSL,
|
||||
}
|
||||
import sbt.util.Applicative
|
||||
import scala.quoted.*
|
||||
|
||||
class InitializeConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
||||
|
|
@ -31,6 +32,9 @@ class InitializeConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
|||
case InputWrapper.WrapPreviousName =>
|
||||
Converted.Failure(in.pos, "A setting cannot depend on a task's previous value.")
|
||||
case _ => Converted.NotApplicable()
|
||||
|
||||
def appExpr: Expr[Applicative[Initialize]] =
|
||||
'{ InitializeInstance.initializeMonad }
|
||||
end InitializeConvert
|
||||
|
||||
object SettingMacro:
|
||||
|
|
@ -41,8 +45,8 @@ object SettingMacro:
|
|||
import ContSyntax.*
|
||||
|
||||
def settingMacroImpl[A1: Type](in: Expr[A1])(using qctx: Quotes): Expr[Initialize[A1]] =
|
||||
val convert1: Convert[qctx.type] = InitializeConvert(qctx)
|
||||
convert1.contMapN[A1, F, Id](in, convert1.idTransform)
|
||||
val convert1 = InitializeConvert(qctx)
|
||||
convert1.contMapN[A1, F, Id](in, convert1.appExpr)
|
||||
|
||||
/*
|
||||
def settingDynMacroImpl[T: c.WeakTypeTag](
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import sbt.internal.util.appmacro.{
|
|||
}
|
||||
// import Instance.Transform
|
||||
import sbt.internal.util.{ AList, LinePosition, NoPosition, SourcePosition, ~> }
|
||||
import sbt.internal.util.complete.Parser
|
||||
|
||||
import language.experimental.macros
|
||||
import scala.annotation.tailrec
|
||||
|
|
@ -56,8 +57,8 @@ object TaskMacro:
|
|||
t match
|
||||
case '{ if ($cond) then $thenp else $elsep } => mkIfS[A1](t)
|
||||
case _ =>
|
||||
val convert1: Convert[qctx.type] = new FullConvert(qctx)
|
||||
convert1.contMapN[A1, F, Id](t, convert1.idTransform)
|
||||
val convert1 = new FullConvert(qctx)
|
||||
convert1.contMapN[A1, F, Id](t, convert1.appExpr)
|
||||
|
||||
def mkIfS[A1: Type](t: Expr[A1])(using qctx: Quotes): Expr[Initialize[Task[A1]]] =
|
||||
t match
|
||||
|
|
@ -69,8 +70,8 @@ object TaskMacro:
|
|||
def taskDynMacroImpl[A1: Type](
|
||||
t: Expr[Initialize[Task[A1]]]
|
||||
)(using qctx: Quotes): Expr[Initialize[Task[A1]]] =
|
||||
val convert1: Convert[qctx.type] = new FullConvert(qctx)
|
||||
convert1.contFlatMap[A1, F, Id](t, convert1.idTransform)
|
||||
val convert1 = new FullConvert(qctx)
|
||||
convert1.contFlatMap[A1, F, Id](t, convert1.appExpr)
|
||||
|
||||
/*
|
||||
def taskIfMacroImpl[A: Type](
|
||||
|
|
@ -157,16 +158,14 @@ object TaskMacro:
|
|||
$rec.set0($app, $sourcePosition)
|
||||
}
|
||||
|
||||
/*
|
||||
/** Implementation of := macro for tasks. */
|
||||
def inputTaskAssignMacroImpl[A1: Type](using
|
||||
def inputTaskAssignMacroImpl[A1: Type](v: Expr[A1])(using
|
||||
qctx: Quotes
|
||||
)(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[A1]]](assign)
|
||||
}
|
||||
*/
|
||||
): Expr[Setting[InputTask[A1]]] =
|
||||
val init = inputTaskMacroImpl[A1](v)
|
||||
// val assign = transformMacroImpl(init.tree)(AssignInitName)
|
||||
// Expr[Setting[InputTask[A1]]](assign)
|
||||
???
|
||||
|
||||
/** Implementation of += macro for settings. */
|
||||
def settingAppend1Impl[A1: Type, A2: Type](rec: Expr[SettingKey[A1]], v: Expr[A2])(using
|
||||
|
|
@ -238,94 +237,97 @@ object TaskMacro:
|
|||
import c.universe._
|
||||
c.Expr[A1](Literal(Constant(t)))
|
||||
}
|
||||
*/
|
||||
|
||||
def inputTaskMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[A1]): c.Expr[Initialize[InputTask[A1]]] =
|
||||
inputTaskMacro0[A1](c)(t)
|
||||
def inputTaskMacroImpl[A1: Type](tree: Expr[A1])(using
|
||||
qctx: Quotes
|
||||
): Expr[Initialize[InputTask[A1]]] =
|
||||
inputTaskMacro0[A1](tree)
|
||||
|
||||
def inputTaskDynMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[InputTask[A1]]] =
|
||||
inputTaskDynMacro0[A1](c)(t)
|
||||
// def inputTaskDynMacroImpl[A1: Type](t: c.Expr[Initialize[Task[A1]]])(using qctx: Quotes): c.Expr[Initialize[InputTask[A1]]] =
|
||||
// inputTaskDynMacro0[A1](c)(t)
|
||||
|
||||
private[this] def inputTaskMacro0[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[A1]): c.Expr[Initialize[InputTask[A1]]] =
|
||||
iInitializeMacro(c)(t) { et =>
|
||||
val pt = iParserMacro(c)(et) { pt =>
|
||||
iTaskMacro(c)(pt)
|
||||
private[this] def inputTaskMacro0[A1: Type](tree: Expr[A1])(using
|
||||
qctx: Quotes
|
||||
): Expr[Initialize[InputTask[A1]]] =
|
||||
iInitializeMacro(tree) { et =>
|
||||
val pt = iParserMacro(et) { pt =>
|
||||
iTaskMacro(pt)
|
||||
}
|
||||
c.universe.reify { InputTask.make(pt.splice) }
|
||||
'{ InputTask.make($pt) }
|
||||
}
|
||||
|
||||
private[this] 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[A1, M](c, InitializeInstance, InputInitConvert, MixedBuilder, EmptyLinter)(
|
||||
Left(cond),
|
||||
inner
|
||||
)
|
||||
}
|
||||
private[this] def iInitializeMacro[F1[_]: Type, A1: Type](tree: Expr[A1])(
|
||||
f: Expr[A1] => Expr[F1[A1]]
|
||||
)(using qctx: Quotes): Expr[Initialize[F1[A1]]] =
|
||||
import qctx.reflect.*
|
||||
import InputWrapper.*
|
||||
val convert1 = new InputInitConvert(qctx)
|
||||
import convert1.Converted
|
||||
|
||||
private[this] def conditionInputTaskTree(c: blackbox.Context)(t: c.Tree): c.Tree = {
|
||||
import c.universe._
|
||||
import InputWrapper._
|
||||
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[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[A1: Type](tree: Tree) = {
|
||||
val e = c.Expr[Initialize[InputTask[A1]]](tree)
|
||||
wrapInput[A1](wrapInit[InputTask[A1]](c)(e, 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 wrapInitTask[A2: Type](tree: Term): Term =
|
||||
val expr = tree.asExprOf[Initialize[Task[A2]]]
|
||||
'{
|
||||
InputWrapper.wrapTask[A2](InputWrapper.wrapInit[A2]($expr))
|
||||
}.asTerm
|
||||
|
||||
def expand(nme: String, tpe: Type, tree: Tree): Converted[c.type] = nme match {
|
||||
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))
|
||||
}
|
||||
def wrapInitParser[A2: Type](tree: Term): Term =
|
||||
val expr = tree.asExprOf[Initialize[State => Parser[A2]]]
|
||||
'{
|
||||
ParserInput.wrap[A2](InputWrapper.wrapInit[State => Parser[A2]]($expr))
|
||||
}.asTerm
|
||||
|
||||
private[this] 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
|
||||
)
|
||||
}
|
||||
def wrapInitInput[A2: Type](tree: Term): Term =
|
||||
val expr = tree.asExprOf[Initialize[InputTask[A2]]]
|
||||
wrapInput[A2]('{
|
||||
InputWrapper.wrapInit[InputTask[A2]]($expr)
|
||||
}.asTerm)
|
||||
|
||||
private[this] def iTaskMacro[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[A1]): c.Expr[Task[A1]] =
|
||||
Instance
|
||||
.contImpl[A1, Id](c, TaskInstance, TaskConvert, MixedBuilder, EmptyLinter)(
|
||||
Left(t),
|
||||
Instance.idTransform
|
||||
def wrapInput[A2: Type](tree: Term): Term =
|
||||
val expr = tree.asExprOf[InputTask[A1]]
|
||||
'{
|
||||
InputWrapper.wrapTask[A2](ParserInput.wrap[Task[A2]]($expr.parser))
|
||||
}.asTerm
|
||||
|
||||
def expand(nme: String, tpeRepr: TypeRepr, tree: Term): Converted =
|
||||
tpeRepr.asType match
|
||||
case '[tpe] =>
|
||||
nme match
|
||||
case WrapInitTaskName => Converted.success(wrapInitTask[tpe](tree))
|
||||
case WrapPreviousName => Converted.success(wrapInitTask[tpe](tree))
|
||||
case ParserInput.WrapInitName => Converted.success(wrapInitParser[tpe](tree))
|
||||
case WrapInitInputName => Converted.success(wrapInitInput[tpe](tree))
|
||||
case WrapInputName => Converted.success(wrapInput[tpe](tree))
|
||||
case _ => Converted.NotApplicable()
|
||||
|
||||
def conditionInputTaskTree(t: Term): Term =
|
||||
convert1.transformWrappers(
|
||||
tree = t,
|
||||
subWrapper = (nme, tpe, tree, original) => expand(nme, tpe, tree),
|
||||
owner = Symbol.spliceOwner,
|
||||
)
|
||||
|
||||
val inner: convert1.TermTransform[F1] = (in: Term) => f(in.asExprOf[A1]).asTerm
|
||||
val cond = conditionInputTaskTree(tree.asTerm).asExprOf[A1]
|
||||
convert1.contMapN[A1, Def.Initialize, F1](cond, convert1.appExpr, inner)
|
||||
|
||||
private[this] def iParserMacro[F1[_]: Type, A1: Type](tree: Expr[A1])(
|
||||
f: Expr[A1] => Expr[F1[A1]]
|
||||
)(using qctx: Quotes): Expr[State => Parser[F1[A1]]] =
|
||||
import qctx.reflect.*
|
||||
val convert1 = new ParserConvert(qctx)
|
||||
val inner: convert1.TermTransform[F1] = (in: Term) => f(in.asExprOf[A1]).asTerm
|
||||
convert1.contMapN[A1, ParserInstance.F1, F1](tree, convert1.appExpr, inner)
|
||||
|
||||
private[this] def iTaskMacro[A1: Type](tree: Expr[A1])(using qctx: Quotes): Expr[Task[A1]] =
|
||||
import qctx.reflect.*
|
||||
val convert1 = new TaskConvert(qctx)
|
||||
convert1.contMapN[A1, Task, Id](tree, convert1.appExpr)
|
||||
|
||||
/*
|
||||
private[this] def inputTaskDynMacro0[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[InputTask[A1]]] = {
|
||||
t: Expr[Initialize[Task[A1]]]
|
||||
)(using qctx: Quotes): Expr[Initialize[InputTask[A1]]] = {
|
||||
import c.universe.{ Apply => ApplyTree, _ }
|
||||
import internal.decorators._
|
||||
|
||||
|
|
@ -406,7 +408,6 @@ object TaskMacro:
|
|||
}
|
||||
}
|
||||
*/
|
||||
|
||||
end TaskMacro
|
||||
|
||||
object DefinableTaskMacro:
|
||||
|
|
|
|||
|
|
@ -10,10 +10,9 @@ package sbt.std
|
|||
import sbt.internal.util.complete
|
||||
import sbt.internal.util.complete.DefaultParsers
|
||||
import sbt.{ Def, InputTask, Task }
|
||||
import sbt.Def.parsed
|
||||
|
||||
object UseTask:
|
||||
import sbt.std.FullInstance.given
|
||||
|
||||
val set = Def.setting { 23 }
|
||||
val x = Def.task { set.value }
|
||||
val y = Def.task { true }
|
||||
|
|
@ -88,9 +87,10 @@ object Assign {
|
|||
// ik := { if (tsk.parsed.value == "blue") tk.value else mk.value }
|
||||
)
|
||||
|
||||
// val it1 = Def.inputTask {
|
||||
// tsk.parsed // "as" //dummy.value.parsed
|
||||
// }
|
||||
val it1 = Def.inputTask {
|
||||
//
|
||||
tsk.parsed // "as" //dummy.value.parsed
|
||||
}
|
||||
// val it2 = Def.inputTask {
|
||||
// "lit"
|
||||
// }
|
||||
|
|
|
|||
Loading…
Reference in New Issue