diff --git a/main-settings/src/main/scala/sbt/Def.scala b/main-settings/src/main/scala/sbt/Def.scala index da40fd7b0..1ad526786 100644 --- a/main-settings/src/main/scala/sbt/Def.scala +++ b/main-settings/src/main/scala/sbt/Def.scala @@ -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) } diff --git a/main-settings/src/main/scala/sbt/Structure.scala b/main-settings/src/main/scala/sbt/Structure.scala index 1212be8e1..c54d6883e 100644 --- a/main-settings/src/main/scala/sbt/Structure.scala +++ b/main-settings/src/main/scala/sbt/Structure.scala @@ -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) diff --git a/main-settings/src/main/scala/sbt/std/TaskMacro.scala b/main-settings/src/main/scala/sbt/std/TaskMacro.scala index 0353d1d3a..2d0901e60 100644 --- a/main-settings/src/main/scala/sbt/std/TaskMacro.scala +++ b/main-settings/src/main/scala/sbt/std/TaskMacro.scala @@ -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] diff --git a/main-settings/src/test/scala/sbt/std/UsageTest.scala b/main-settings/src/test/scala/sbt/std/UsageTest.scala index 4f70889ce..25f943814 100644 --- a/main-settings/src/test/scala/sbt/std/UsageTest.scala +++ b/main-settings/src/test/scala/sbt/std/UsageTest.scala @@ -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 }