Starting input task

This commit is contained in:
Eugene Yokota 2022-06-20 01:58:45 -04:00
parent b715917d95
commit f3dd2dff36
12 changed files with 216 additions and 167 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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