Inline append macros

This commit is contained in:
Eugene Yokota 2022-06-06 00:55:24 -04:00
parent a1e50f8a2e
commit b715917d95
4 changed files with 105 additions and 238 deletions

View File

@ -221,7 +221,7 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits:
import std.TaskMacro.{
// inputTaskDynMacroImpl,
// inputTaskMacroImpl,
// taskDynMacroImpl,
taskDynMacroImpl,
// taskIfMacroImpl,
taskMacroImpl,
}
@ -232,7 +232,8 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits:
inline def task[A1](inline a1: A1): Def.Initialize[Task[A1]] =
${ taskMacroImpl[A1]('a1) }
// def taskDyn[T](t: Def.Initialize[Task[T]]): Def.Initialize[Task[T]] = macro taskDynMacroImpl[T]
inline def taskDyn[A1](a1: Def.Initialize[Task[A1]]): Def.Initialize[Task[A1]] =
${ taskDynMacroImpl[A1]('a1) }
inline def setting[A1](inline a: A1): Def.Initialize[A1] = ${ settingMacroImpl[A1]('a) }

View File

@ -73,14 +73,26 @@ sealed abstract class SettingKey[A1]
final def in(scope: Scope): SettingKey[A1] =
Scoped.scopedSetting(Scope.replaceThis(this.scope)(scope), this.key)
/** Internal function for the setting macro. */
inline def settingMacro[A](inline a: A): Initialize[A] =
${ std.SettingMacro.settingMacroImpl[A]('a) }
final inline def :=(inline v: A1): Setting[A1] =
${ TaskMacro.settingAssignMacroImpl('this, 'v) }
final inline def +=[A2](inline v: A2)(using a: Append.Value[A1, A2]): Setting[A1] =
final inline def +=[A2](inline v: A2)(using Append.Value[A1, A2]): Setting[A1] =
${ TaskMacro.settingAppend1Impl[A1, A2]('this, 'v) }
final inline def ++=[A2](inline vs: A2)(using a: Append.Values[A1, A2]): Setting[A1] =
${ TaskMacro.settingAppendNImpl[A1, A2]('this, 'vs) }
final inline def append1[A2](v: Initialize[A2])(using
a: Append.Value[A1, A2]
): Setting[A1] = make(v)(a.appendValue)
final inline def ++=[A2](inline vs: A2)(using Append.Values[A1, A2]): Setting[A1] =
appendN(settingMacro[A2](vs))
final def appendN[V](vs: Initialize[V])(using
ev: Append.Values[A1, V]
): Setting[A1] = make(vs)(ev.appendValues)
final inline def <+=[A2](inline v: Initialize[A2]): Setting[A1] =
${ TaskMacro.fakeSettingAppend1Position[A1, A2]('v) }
@ -89,33 +101,28 @@ sealed abstract class SettingKey[A1]
${ TaskMacro.fakeSettingAppendNPosition[A1, A2]('vs) }
final inline def -=[A2](inline v: A2)(using Remove.Value[A1, A2]): Setting[A1] =
${ TaskMacro.settingRemove1Impl[A1, A2]('this, 'v) }
remove1(settingMacro[A2](v))
final inline def remove1[V](v: Initialize[V])(using
ev: Remove.Value[A1, V]
): Setting[A1] = make(v)(ev.removeValue)
final inline def --=[A2](inline vs: A2)(using Remove.Values[A1, A2]): Setting[A1] =
${ TaskMacro.settingRemoveNImpl[A1, A2]('this, 'vs) }
removeN(settingMacro[A2](vs))
final inline def removeN[V](vs: Initialize[V])(using
ev: Remove.Values[A1, V]
): Setting[A1] = make(vs)(ev.removeValues)
final inline def ~=(f: A1 => A1): Setting[A1] = transform(f)
final inline def transform(f: A1 => A1): Setting[A1] = set(scopedKey(f))
final def append1[A2](v: Initialize[A2], source: SourcePosition)(using
a: Append.Value[A1, A2]
): Setting[A1] = make(v, source)(a.appendValue)
inline def make[A2](other: Initialize[A2])(f: (A1, A2) => A1): Setting[A1] =
set(this.zipWith(other)(f))
final def appendN[V](vs: Initialize[V], source: SourcePosition)(using
a: Append.Values[A1, V]
): Setting[A1] = make(vs, source)(a.appendValues)
final def remove1[V](v: Initialize[V], source: SourcePosition)(using
r: Remove.Value[A1, V]
): Setting[A1] = make(v, source)(r.removeValue)
final def removeN[V](vs: Initialize[V], source: SourcePosition)(using
r: Remove.Values[A1, V]
): Setting[A1] = make(vs, source)(r.removeValues)
protected[this] def make[S](other: Initialize[S], source: SourcePosition)(
f: (A1, S) => A1
protected[this] inline def make[A2](other: Initialize[A2], source: SourcePosition)(
f: (A1, A2) => A1
): Setting[A1] = set0(this.zipWith(other)(f), source)
final def withRank(rank: Int): SettingKey[A1] =
@ -149,10 +156,19 @@ sealed abstract class TaskKey[A1]
Scoped.scopedTask(Scope.replaceThis(this.scope)(scope), this.key)
inline def +=[A2](inline v: A2)(using Append.Value[A1, A2]): Setting[Task[A1]] =
${ TaskMacro.taskAppend1Impl[A1, A2]('this, 'v) }
append1[A2](taskMacro(v))
inline def append1[A2](v: Initialize[Task[A2]])(using
ev: Append.Value[A1, A2]
): Setting[Task[A1]] =
make(v)(ev.appendValue)
inline def ++=[A2](inline vs: A2)(using Append.Values[A1, A2]): Setting[Task[A1]] =
${ TaskMacro.taskAppendNImpl[A1, A2]('this, 'vs) }
appendN(taskMacro[A2](vs))
inline def appendN[A2](vs: Initialize[Task[A2]])(using
ev: Append.Values[A1, A2]
): Setting[Task[A1]] = make(vs)(ev.appendValues)
inline def <+=[A2](inline v: Initialize[Task[A2]]): Setting[Task[A1]] =
${ TaskMacro.fakeTaskAppend1Position[A1, A2]('v) }
@ -160,32 +176,28 @@ sealed abstract class TaskKey[A1]
inline def <++=[A2](inline vs: Initialize[Task[A2]]): Setting[Task[A1]] =
${ TaskMacro.fakeTaskAppendNPosition[A1, A2]('vs) }
final inline def -=[A2](v: A2)(using r: Remove.Value[A1, A2]): Setting[Task[A1]] =
${ TaskMacro.taskRemove1Impl[A1, A2]('this, 'v) }
final inline def -=[A2](v: A2)(using Remove.Value[A1, A2]): Setting[Task[A1]] =
remove1[A2](taskMacro[A2](v))
final inline def remove1[A2](v: Initialize[Task[A2]])(using
ev: Remove.Value[A1, A2]
): Setting[Task[A1]] = make(v)(ev.removeValue)
final inline def --=[A2](vs: A2)(using r: Remove.Values[A1, A2]): Setting[Task[A1]] =
${ TaskMacro.taskRemoveNImpl[A1, A2]('this, 'vs) }
removeN[A2](taskMacro[A2](vs))
def append1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit
a: Append.Value[A1, V]
): Setting[Task[A1]] = make(v, source)(a.appendValue)
final inline def removeN[A2](vs: Initialize[Task[A2]])(using
ev: Remove.Values[A1, A2]
): Setting[Task[A1]] = make(vs)(ev.removeValues)
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[A1, V]
): Setting[Task[A1]] = make(v, source)(r.removeValue)
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)(
inline def make[S](other: Initialize[Task[S]], source: SourcePosition)(
f: (A1, S) => A1
): Setting[Task[A1]] = set0(this.zipWith(other)((a, b) => (a, b) map f.tupled), source)
inline def make[S](other: Initialize[Task[S]])(
f: (A1, S) => A1
): Setting[Task[A1]] = set(this.zipWith(other)((a, b) => (a, b) map f.tupled))
final def withRank(rank: Int): TaskKey[A1] =
TaskKey(AttributeKey.copyWithRank(key, rank))
@ -299,11 +311,13 @@ object Scoped:
sealed trait DefinableSetting[A1] { self =>
def scopedKey: ScopedKey[A1]
// private[sbt] final def :==(app: S): Setting[S] = macro std.TaskMacro.settingAssignPure[S]
private[sbt] final inline def :==(inline app: A1): Setting[A1] =
set(Def.valueStrict(app))
inline def <<=(inline app: Initialize[A1]): Setting[A1] =
${ TaskMacro.fakeSettingAssignImpl('app) }
/** In addition to creating Def.setting(...), this captures the source position. */
inline def set(inline app: Initialize[A1]): Setting[A1] =
${ TaskMacro.settingSetImpl('self, 'app) }
@ -363,21 +377,25 @@ object Scoped:
sealed trait DefinableTask[A1] { self: TaskKey[A1] =>
/** Internal function for the task macro. */
inline def taskMacro[A](inline a: A): Initialize[Task[A]] =
${ TaskMacro.taskMacroImpl[A]('a) }
private[sbt] inline def :==(app: A1): Setting[Task[A1]] =
set(Def.valueStrict(std.TaskExtra.constant(app)))
private[sbt] inline def ::=(app: Task[A1]): Setting[Task[A1]] =
set(Def.valueStrict(app))
inline def :=(inline v: A1): Setting[Task[A1]] =
${ TaskMacro.taskAssignMacroImpl[A1]('self, 'v) }
inline def :=(inline a: A1): Setting[Task[A1]] =
set(taskMacro(a))
inline def <<=(inline app: Initialize[Task[A1]]): Setting[Task[A1]] =
${ TaskMacro.fakeItaskAssignPosition[A1]('app) }
/** In addition to creating Def.setting(...), this captures the source position. */
inline def set(inline app: Initialize[Task[A1]]): Setting[Task[A1]] =
${ TaskMacro.taskSetImpl('self, 'app) }
${ std.DefinableTaskMacro.taskSetImpl('self, 'app) }
private[sbt] def set0(app: Initialize[Task[A1]], source: SourcePosition): Setting[Task[A1]] =
Def.setting(scopedKey, app, source)

View File

@ -28,26 +28,6 @@ import scala.annotation.tailrec
import scala.reflect.internal.util.UndefinedPosition
import scala.quoted.*
/** Instance for the monad/applicative functor for plain Tasks. */
/*
object TaskInstance:
import 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 TaskInstance
*/
object TaskMacro:
final val AssignInitName = "set"
final val Append1InitName = "append1"
@ -86,15 +66,13 @@ object TaskMacro:
Def.ifS[A1](Def.task($cond))(Def.task[A1]($thenp))(Def.task[A1]($elsep))
}
/*
def taskDynMacroImpl[A1: Type](
c: blackbox.Context
)(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]
)
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)
/*
def taskIfMacroImpl[A: Type](
c: blackbox.Context
)(a: c.Expr[A]): c.Expr[Initialize[Task[A]]] = {
@ -119,16 +97,6 @@ object TaskMacro:
$rec.set0($init, $sourcePosition)
}
/** Implementation of := macro for tasks. */
def taskAssignMacroImpl[A1: Type](rec: Expr[Scoped.DefinableTask[A1]], v: Expr[A1])(using
qctx: Quotes
): Expr[Setting[Task[A1]]] =
import qctx.reflect.*
val init = taskMacroImpl[A1](v)
'{
$rec.set0($init, $sourcePosition)
}
// Error macros (Restligeist)
// These macros are there just so we can fail old operators like `<<=` and provide useful migration information.
@ -179,18 +147,6 @@ object TaskMacro:
// Implementations of <<= macro variations for tasks and settings.
// These just get the source position of the call site.
/*
def itaskAssignPosition[A1: Type](using
qctx: Quotes
)(app: Expr[Initialize[Task[A1]]]): Expr[Setting[Task[A1]]] =
settingAssignPosition(app)
def taskAssignPositionT[A1: Type](app: Expr[Task[A1]])(using
qctx: Quotes
): Expr[Setting[Task[A1]]] =
itaskAssignPosition(universe.reify { Def.valueStrict(app.splice) })
*/
def settingSetImpl[A1: Type](
rec: Expr[Scoped.DefinableSetting[A1]],
app: Expr[Def.Initialize[A1]]
@ -201,37 +157,6 @@ object TaskMacro:
$rec.set0($app, $sourcePosition)
}
def taskSetImpl[A1: Type](rec: Expr[TaskKey[A1]], app: Expr[Def.Initialize[Task[A1]]])(using
qctx: Quotes
): Expr[Setting[Task[A1]]] =
'{
$rec.set0($app, $sourcePosition)
}
// def taskTransformPosition[A1: Type](f: Expr[A1 => A1])(using
// qctx: Quotes
// ): Expr[Setting[Task[A1]]] =
// Expr[Setting[Task[S]]](transformMacroImpl(c)(f.tree)(TransformInitName))
/*
def itaskTransformPosition[S: Type](using
qctx: Quotes
)(f: c.Expr[S => S]): c.Expr[Setting[S]] =
c.Expr[Setting[S]](transformMacroImpl(c)(f.tree)(TransformInitName))
def settingAssignPure[A1: Type](using
qctx: Quotes)(app: c.Expr[A1]): c.Expr[Setting[A1]] =
settingAssignPosition(c)(c.universe.reify { Def.valueStrict(app.splice) })
*/
def settingAssignPosition[A1: Type](rec: Expr[SettingKey[A1]], app: Expr[Initialize[A1]])(using
qctx: Quotes
): Expr[Setting[A1]] =
'{
$rec.set0($app, $sourcePosition)
}
/*
/** Implementation of := macro for tasks. */
def inputTaskAssignMacroImpl[A1: Type](using
@ -243,20 +168,6 @@ object TaskMacro:
}
*/
/** Implementation of += macro for tasks. */
def taskAppend1Impl[A1: Type, A2: Type](rec: Expr[TaskKey[A1]], v: Expr[A2])(using
qctx: Quotes
): Expr[Setting[Task[A1]]] =
import qctx.reflect.*
Expr.summon[Append.Value[A1, A2]] match
case Some(ev) =>
val init = taskMacroImpl[A2](v)
'{
$rec.append1[A2]($init, $sourcePosition)(using $ev)
}
case _ =>
report.errorAndAbort(s"Append.Value[${Type.of[A1]}, ${Type.of[A2]}] missing")
/** Implementation of += macro for settings. */
def settingAppend1Impl[A1: Type, A2: Type](rec: Expr[SettingKey[A1]], v: Expr[A2])(using
qctx: Quotes,
@ -279,88 +190,10 @@ object TaskMacro:
case Some(ev) =>
val init = SettingMacro.settingMacroImpl[A2](v)
'{
$rec.append1[A2]($init, $sourcePosition)(using $ev)
$rec.append1[A2]($init)(using $ev)
}
case _ => report.errorAndAbort(s"Append.Value[${Type.of[A1]}, ${Type.of[A2]}] missing")
/** Implementation of ++= macro for tasks. */
def taskAppendNImpl[A1: Type, A2: Type](rec: Expr[TaskKey[A1]], vs: Expr[A2])(using
qctx: Quotes
): Expr[Setting[Task[A1]]] =
import qctx.reflect.*
Expr.summon[Append.Values[A1, A2]] match
case Some(ev) =>
val init = taskMacroImpl[A2](vs)
'{
$rec.appendN($init, $sourcePosition)(using $ev)
}
case _ => report.errorAndAbort(s"Append.Values[${Type.of[A1]}, ${Type.of[A2]}] missing")
/** Implementation of ++= macro for settings. */
def settingAppendNImpl[A1: Type, A2: Type](rec: Expr[SettingKey[A1]], vs: Expr[A2])(using
qctx: Quotes
): Expr[Setting[A1]] =
import qctx.reflect.*
Expr.summon[Append.Values[A1, A2]] match
case Some(ev) =>
val init = SettingMacro.settingMacroImpl[A2](vs)
'{
$rec.appendN($init, $sourcePosition)(using $ev)
}
case _ => report.errorAndAbort(s"Append.Values[${Type.of[A1]}, ${Type.of[A2]}] missing")
/** Implementation of -= macro for tasks. */
def taskRemove1Impl[A1: Type, A2: Type](rec: Expr[TaskKey[A1]], v: Expr[A2])(using
qctx: Quotes
): Expr[Setting[Task[A1]]] =
import qctx.reflect.*
Expr.summon[Remove.Value[A1, A2]] match
case Some(ev) =>
val init = taskMacroImpl[A2](v)
'{
$rec.remove1[A2]($init, $sourcePosition)(using $ev)
}
case _ => report.errorAndAbort(s"Remove.Value[${Type.of[A1]}, ${Type.of[A2]}] missing")
/** Implementation of -= macro for settings. */
def settingRemove1Impl[A1: Type, A2: Type](rec: Expr[SettingKey[A1]], v: Expr[A2])(using
qctx: Quotes
): Expr[Setting[A1]] =
import qctx.reflect.*
Expr.summon[Remove.Value[A1, A2]] match
case Some(ev) =>
val init = SettingMacro.settingMacroImpl[A2](v)
'{
$rec.remove1[A2]($init, $sourcePosition)(using $ev)
}
case _ => report.errorAndAbort(s"Remove.Value[${Type.of[A1]}, ${Type.of[A2]}] missing")
/** Implementation of --= macro for tasks. */
def taskRemoveNImpl[A1: Type, A2: Type](rec: Expr[TaskKey[A1]], vs: Expr[A2])(using
qctx: Quotes
): Expr[Setting[Task[A1]]] =
import qctx.reflect.*
Expr.summon[Remove.Values[A1, A2]] match
case Some(ev) =>
val init = taskMacroImpl[A2](vs)
'{
$rec.removeN[A2]($init, $sourcePosition)(using $ev)
}
case _ => report.errorAndAbort(s"Remove.Values[${Type.of[A1]}, ${Type.of[A2]}] missing")
/** Implementation of --= macro for settings. */
def settingRemoveNImpl[A1: Type, A2: Type](rec: Expr[SettingKey[A1]], vs: Expr[A2])(using
qctx: Quotes
): Expr[Setting[A1]] =
import qctx.reflect.*
Expr.summon[Remove.Values[A1, A2]] match
case Some(ev) =>
val init = SettingMacro.settingMacroImpl[A2](vs)
'{
$rec.removeN[A2]($init, $sourcePosition)(using $ev)
}
case _ => report.errorAndAbort(s"Remove.Values[${Type.of[A1]}, ${Type.of[A2]}] missing")
/*
private[this] def transformMacroImpl[A](using qctx: Quotes)(init: Expr[A])(
newName: String
@ -378,7 +211,7 @@ object TaskMacro:
}
*/
private[this] def sourcePosition(using qctx: Quotes): Expr[SourcePosition] =
private[sbt] def sourcePosition(using qctx: Quotes): Expr[SourcePosition] =
import qctx.reflect.*
val pos = Position.ofMacroExpansion
if pos.startLine >= 0 && pos.sourceCode != None then
@ -576,6 +409,19 @@ object TaskMacro:
end TaskMacro
object DefinableTaskMacro:
def taskSetImpl[A1: Type](
rec: Expr[Scoped.DefinableTask[A1]],
app: Expr[Def.Initialize[Task[A1]]]
)(using
qctx: Quotes
): Expr[Setting[Task[A1]]] =
val pos = TaskMacro.sourcePosition
'{
$rec.set0($app, $pos)
}
end DefinableTaskMacro
/*
object PlainTaskMacro:
def task[A1](t: T): Task[A1] = macro taskImpl[A1]

View File

@ -11,20 +11,21 @@ import sbt.internal.util.complete
import sbt.internal.util.complete.DefaultParsers
import sbt.{ Def, InputTask, Task }
/*object UseTask
{
import Def._
object UseTask:
import sbt.std.FullInstance.given
val set = setting { 23 }
val plain = PlainTaskMacro task { 19 }
val set = Def.setting { 23 }
val x = Def.task { set.value }
val y = Def.task { true }
val z = Def.task { if (y.value) x.value else set.value }
val a = Def.taskDyn {
// if y.value then z
// else x
if true then z
else x
}
end UseTask
val x = task { set.value }
val y = task { true }
val z = task { if(y.value) x.value else plain.value }
val a = taskDyn {
if(y.value) z else x
}
}*/
object Assign {
import java.io.File
@ -56,7 +57,7 @@ object Assign {
val seqSetting = settingKey[Seq[String]]("seqSetting")
val listSetting = settingKey[List[String]]("listSetting")
val listTask = taskKey[List[String]]("listTask")
val listTask = taskKey[List[Int]]("listTask")
/* def azy = sk.value
@ -137,6 +138,7 @@ object Assign {
listSetting ~= { (xs) => xs }
listTask := List("test1")
listTask += "test2"
listTask := List(1)
listTask += 1
listTask += ak.value
}