mirror of https://github.com/sbt/sbt.git
Setting macro
This commit is contained in:
parent
2f50a88a3d
commit
37f6ee6184
|
|
@ -214,7 +214,10 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits:
|
|||
def toISParser[T](p: Initialize[Parser[T]]): Initialize[State => Parser[T]] = p(toSParser)
|
||||
def toIParser[T](p: Initialize[InputTask[T]]): Initialize[State => Parser[Task[T]]] = p(_.parser)
|
||||
|
||||
// import std.SettingMacro.{ settingDynMacroImpl, settingMacroImpl }
|
||||
import std.SettingMacro.{
|
||||
// settingDynMacroImpl,
|
||||
settingMacroImpl
|
||||
}
|
||||
import std.TaskMacro.{
|
||||
// inputTaskDynMacroImpl,
|
||||
// inputTaskMacroImpl,
|
||||
|
|
@ -230,7 +233,9 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits:
|
|||
${ taskMacroImpl[A1]('a1) }
|
||||
|
||||
// def taskDyn[T](t: Def.Initialize[Task[T]]): Def.Initialize[Task[T]] = macro taskDynMacroImpl[T]
|
||||
// def setting[T](t: T): Def.Initialize[T] = macro settingMacroImpl[T]
|
||||
|
||||
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]] = {
|
||||
|
|
@ -290,14 +295,16 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits:
|
|||
@targetName("valueIA1")
|
||||
inline def value: A1 = InputWrapper.`wrapInitTask_\u2603\u2603`[A1](in)
|
||||
|
||||
/**
|
||||
* This treats the `Initailize[Task[A]]` as a setting that returns the Task value,
|
||||
* instead of evaluating the task.
|
||||
*/
|
||||
inline def taskValue: Task[A1] = InputWrapper.`wrapInit_\u2603\u2603`[Task[A1]](in)
|
||||
|
||||
// implicit def macroValueIInT[T](
|
||||
// @deprecated("unused", "") in: Initialize[InputTask[T]]
|
||||
// ): InputEvaluated[T] = ???
|
||||
|
||||
// implicit def taskMacroValueIT[T](
|
||||
// @deprecated("unused", "") in: Initialize[Task[T]]
|
||||
// ): MacroTaskValue[T] = ???
|
||||
|
||||
// implicit def macroPrevious[T](@deprecated("unused", "") in: TaskKey[T]): MacroPrevious[T] = ???
|
||||
|
||||
// The following conversions enable the types Parser[T], Initialize[Parser[T]], and
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import sbt.internal.util.{ ~>, AList, AttributeKey, Settings, SourcePosition }
|
|||
import sbt.util.OptJsonWriter
|
||||
import sbt.ConcurrentRestrictions.Tag
|
||||
import sbt.Def.{ Initialize, ScopedKey, Setting, setting }
|
||||
import std.TaskMacro
|
||||
import std.TaskExtra.{ task => mktask, _ }
|
||||
|
||||
/** An abstraction on top of Settings for build configuration and task definition. */
|
||||
|
|
@ -72,30 +73,32 @@ sealed abstract class SettingKey[A1]
|
|||
final def in(scope: Scope): SettingKey[A1] =
|
||||
Scoped.scopedSetting(Scope.replaceThis(this.scope)(scope), this.key)
|
||||
|
||||
// final def :=(v: T): Setting[T] = macro std.TaskMacro.settingAssignMacroImpl[T]
|
||||
final inline def :=(inline v: A1): Setting[A1] =
|
||||
${ TaskMacro.settingAssignMacroImpl('this, 'v) }
|
||||
|
||||
// final def +=[U](v: U)(implicit a: Append.Value[T, U]): Setting[T] =
|
||||
// macro std.TaskMacro.settingAppend1Impl[T, U]
|
||||
final inline def +=[A2](inline v: A2)(using a: Append.Value[A1, A2]): Setting[A1] =
|
||||
${ TaskMacro.settingAppend1Impl[A1, A2]('this, 'v) }
|
||||
|
||||
// final def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[T] =
|
||||
// macro std.TaskMacro.settingAppendNImpl[T, U]
|
||||
final inline def ++=[A2](inline vs: A2)(using a: Append.Values[A1, A2]): Setting[A1] =
|
||||
${ TaskMacro.settingAppendNImpl[A1, A2]('this, 'vs) }
|
||||
|
||||
// final def <+=[V](v: Initialize[V])(implicit a: Append.Value[T, V]): Setting[T] =
|
||||
// macro std.TaskMacro.fakeSettingAppend1Position[T, V]
|
||||
final inline def <+=[A2](inline v: Initialize[A2]): Setting[A1] =
|
||||
${ TaskMacro.fakeSettingAppend1Position[A1, A2]('v) }
|
||||
|
||||
// final def <++=[V](vs: Initialize[V])(implicit a: Append.Values[T, V]): Setting[T] =
|
||||
// macro std.TaskMacro.fakeSettingAppendNPosition[T, V]
|
||||
final inline def <++=[A2](inline vs: Initialize[A2]): Setting[A1] =
|
||||
${ TaskMacro.fakeSettingAppendNPosition[A1, A2]('vs) }
|
||||
|
||||
// final def -=[U](v: U)(implicit r: Remove.Value[T, U]): Setting[T] =
|
||||
// macro std.TaskMacro.settingRemove1Impl[T, U]
|
||||
final inline def -=[A2](inline v: A2)(using Remove.Value[A1, A2]): Setting[A1] =
|
||||
${ TaskMacro.settingRemove1Impl[A1, A2]('this, 'v) }
|
||||
|
||||
// final def --=[U](vs: U)(implicit r: Remove.Values[T, U]): Setting[T] =
|
||||
// macro std.TaskMacro.settingRemoveNImpl[T, U]
|
||||
final inline def --=[A2](inline vs: A2)(using Remove.Values[A1, A2]): Setting[A1] =
|
||||
${ TaskMacro.settingRemoveNImpl[A1, A2]('this, 'vs) }
|
||||
|
||||
// final def ~=(f: T => T): Setting[T] = macro std.TaskMacro.settingTransformPosition[T]
|
||||
final inline def ~=(inline f: A1 => A1): Setting[A1] =
|
||||
${ TaskMacro.settingTransformPosition('this, 'f) }
|
||||
|
||||
final def append1[V](v: Initialize[V], source: SourcePosition)(implicit
|
||||
a: Append.Value[A1, V]
|
||||
final def append1[A2](v: Initialize[A2], source: SourcePosition)(using
|
||||
a: Append.Value[A1, A2]
|
||||
): Setting[A1] = make(v, source)(a.appendValue)
|
||||
|
||||
final def appendN[V](vs: Initialize[V], source: SourcePosition)(implicit
|
||||
|
|
@ -212,7 +215,7 @@ sealed trait InputKey[A1]
|
|||
def in(scope: Scope): InputKey[A1] =
|
||||
Scoped.scopedInput(Scope.replaceThis(this.scope)(scope), this.key)
|
||||
|
||||
// final def :=(v: A1): Setting[InputTask[A1]] = macro std.TaskMacro.inputTaskAssignMacroImpl[A1]
|
||||
// inline def :=(inline v: A1): Setting[InputTask[A1]] = macro std.TaskMacro.inputTaskAssignMacroImpl[A1]
|
||||
// final def ~=(f: A1 => A1): Setting[InputTask[A1]] = macro std.TaskMacro.itaskTransformPosition[A1]
|
||||
|
||||
final def transform(f: A1 => A1, source: SourcePosition): Setting[InputTask[A1]] =
|
||||
|
|
@ -297,8 +300,9 @@ object Scoped:
|
|||
|
||||
// private[sbt] final def :==(app: S): Setting[S] = macro std.TaskMacro.settingAssignPure[S]
|
||||
|
||||
// final def <<=(app: Initialize[S]): Setting[S] =
|
||||
// macro std.TaskMacro.fakeSettingAssignPosition[S]
|
||||
inline def <<=(inline app: Initialize[S]): Setting[S] = ${
|
||||
TaskMacro.fakeSettingAssignImpl('app)
|
||||
}
|
||||
|
||||
/** Internally used function for setting a value along with the `.sbt` file location where it is defined. */
|
||||
final def set(app: Initialize[S], source: SourcePosition): Setting[S] =
|
||||
|
|
@ -361,7 +365,11 @@ object Scoped:
|
|||
// private[sbt] def ::=(app: Task[S]): Setting[Task[S]] =
|
||||
// macro std.TaskMacro.taskAssignPositionT[S]
|
||||
|
||||
// def :=(v: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignMacroImpl[S]
|
||||
inline def :=(inline v: A1): Setting[Task[A1]] = ${
|
||||
TaskMacro.taskAssignMacroImpl[A1]('self, 'v)
|
||||
}
|
||||
// macro std.TaskMacro.taskAssignMacroImpl[S]
|
||||
|
||||
// def ~=(f: S => S): Setting[Task[S]] = macro std.TaskMacro.taskTransformPosition[S]
|
||||
|
||||
// def <<=(app: Initialize[Task[S]]): Setting[Task[S]] =
|
||||
|
|
|
|||
|
|
@ -9,53 +9,42 @@ package sbt
|
|||
package std
|
||||
|
||||
import Def.Initialize
|
||||
// import sbt.internal.util.Types.{ Id, idFun }
|
||||
// import sbt.internal.util.AList
|
||||
// import sbt.internal.util.appmacro.{
|
||||
// Convert,
|
||||
// Converted,
|
||||
// Instance,
|
||||
// LinterDSL,
|
||||
// MixedBuilder,
|
||||
// MonadInstance
|
||||
// }
|
||||
import sbt.internal.util.Types.Id
|
||||
import sbt.internal.util.appmacro.{
|
||||
Cont,
|
||||
ContextUtil,
|
||||
Convert,
|
||||
// LinterDSL,
|
||||
}
|
||||
import scala.quoted.*
|
||||
|
||||
class InitializeConvert[C <: Quotes & scala.Singleton](override val qctx: C)
|
||||
extends Convert[C](qctx)
|
||||
with ContextUtil[C](qctx):
|
||||
import qctx.reflect.*
|
||||
|
||||
override def convert[A: Type](nme: String, in: Term): Converted =
|
||||
nme match
|
||||
case InputWrapper.WrapInitName => Converted.success(in)
|
||||
case InputWrapper.WrapTaskName | InputWrapper.WrapInitTaskName =>
|
||||
Converted.Failure(in.pos, "A setting cannot depend on a task")
|
||||
case InputWrapper.WrapPreviousName =>
|
||||
Converted.Failure(in.pos, "A setting cannot depend on a task's previous value.")
|
||||
case _ => Converted.NotApplicable()
|
||||
end InitializeConvert
|
||||
|
||||
object SettingMacro:
|
||||
// import LinterDSL.{ Empty => EmptyLinter }
|
||||
|
||||
type F[x] = Initialize[x]
|
||||
object ContSyntax extends Cont
|
||||
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)
|
||||
|
||||
/*
|
||||
import reflect.macros._
|
||||
|
||||
object InitializeConvert extends Convert {
|
||||
def apply[T: c.WeakTypeTag](c: blackbox.Context)(nme: String, in: c.Tree): Converted[c.type] =
|
||||
nme match {
|
||||
case InputWrapper.WrapInitName => convert[T](c)(in)
|
||||
case InputWrapper.WrapTaskName | InputWrapper.WrapInitTaskName => failTask[c.type](c)(in.pos)
|
||||
case InputWrapper.WrapPreviousName => failPrevious[c.type](c)(in.pos)
|
||||
case _ => Converted.NotApplicable
|
||||
}
|
||||
|
||||
private def convert[T: c.WeakTypeTag](c: blackbox.Context)(in: c.Tree): Converted[c.type] = {
|
||||
val i = c.Expr[Initialize[T]](in)
|
||||
val t = c.universe.reify(i.splice).tree
|
||||
Converted.Success(t)
|
||||
}
|
||||
|
||||
private def failTask[C <: blackbox.Context with Singleton](
|
||||
c: C
|
||||
)(pos: c.Position): Converted[c.type] =
|
||||
Converted.Failure(pos, "A setting cannot depend on a task")
|
||||
private def failPrevious[C <: blackbox.Context with Singleton](
|
||||
c: C
|
||||
)(pos: c.Position): Converted[c.type] =
|
||||
Converted.Failure(pos, "A setting cannot depend on a task's previous value.")
|
||||
}
|
||||
|
||||
object SettingMacro {
|
||||
import LinterDSL.{ Empty => EmptyLinter }
|
||||
def settingMacroImpl[T: c.WeakTypeTag](c: blackbox.Context)(t: c.Expr[T]): c.Expr[Initialize[T]] =
|
||||
Instance.contImpl[T, Id](c, InitializeInstance, InitializeConvert, MixedBuilder, EmptyLinter)(
|
||||
Left(t),
|
||||
Instance.idTransform[c.type]
|
||||
)
|
||||
|
||||
def settingDynMacroImpl[T: c.WeakTypeTag](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[Initialize[T]]): c.Expr[Initialize[T]] =
|
||||
|
|
@ -63,5 +52,6 @@ object SettingMacro {
|
|||
Right(t),
|
||||
Instance.idTransform[c.type]
|
||||
)
|
||||
}
|
||||
*/
|
||||
|
||||
end SettingMacro
|
||||
|
|
|
|||
|
|
@ -79,16 +79,14 @@ object TaskMacro:
|
|||
val convert1: Convert[qctx.type] = new FullConvert(qctx)
|
||||
convert1.contMapN[A1, F, Id](t, convert1.idTransform)
|
||||
|
||||
def mkIfS[A1: Type](using
|
||||
qctx: Quotes
|
||||
)(t: Expr[A1]): Expr[Initialize[Task[A1]]] =
|
||||
def mkIfS[A1: Type](t: Expr[A1])(using qctx: Quotes): Expr[Initialize[Task[A1]]] =
|
||||
t match
|
||||
case '{ if ($cond) then $thenp else $elsep } =>
|
||||
'{
|
||||
Def.ifS[A1](Def.task($cond))(Def.task[A1]($thenp))(Def.task[A1]($elsep))
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
def taskDynMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[Task[A1]]] =
|
||||
|
|
@ -109,110 +107,126 @@ object TaskMacro:
|
|||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/** Implementation of := macro for settings. */
|
||||
def settingAssignMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[A1]): c.Expr[Setting[A1]] = {
|
||||
val init = SettingMacro.settingMacroImpl[A1](c)(v)
|
||||
val assign = transformMacroImpl(c)(init.tree)(AssignInitName)
|
||||
c.Expr[Setting[A1]](assign)
|
||||
}
|
||||
def settingAssignMacroImpl[A1: Type](rec: Expr[Scoped.DefinableSetting[A1]], v: Expr[A1])(using
|
||||
qctx: Quotes
|
||||
): Expr[Setting[A1]] =
|
||||
import qctx.reflect.*
|
||||
val init = SettingMacro.settingMacroImpl[A1](v)
|
||||
'{
|
||||
$rec.set($init, $sourcePosition)
|
||||
}
|
||||
|
||||
/** Implementation of := macro for tasks. */
|
||||
def taskAssignMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[A1]): c.Expr[Setting[Task[A1]]] = {
|
||||
val init = taskMacroImpl[A1](c)(v)
|
||||
val assign = transformMacroImpl(c)(init.tree)(AssignInitName)
|
||||
c.Expr[Setting[Task[A1]]](assign)
|
||||
}
|
||||
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.set($init, $sourcePosition)
|
||||
}
|
||||
|
||||
// Error macros (Restligeist)
|
||||
// These macros are there just so we can fail old operators like `<<=` and provide useful migration information.
|
||||
|
||||
def fakeSettingAssignPosition[A1: Type](c: blackbox.Context)(
|
||||
@deprecated("unused", "") app: c.Expr[Initialize[A1]]
|
||||
): c.Expr[Setting[A1]] =
|
||||
ContextUtil.selectMacroImpl[Setting[A1]](c)((_, pos) => c.abort(pos, assignMigration))
|
||||
def fakeSettingAssignImpl[A1: Type](app: Expr[Initialize[A1]])(using
|
||||
qctx: Quotes
|
||||
): Expr[Setting[A1]] =
|
||||
import qctx.reflect.*
|
||||
report.errorAndAbort(TaskMacro.assignMigration)
|
||||
|
||||
def fakeSettingAppend1Position[S: Type, V: Type](
|
||||
c: blackbox.Context
|
||||
)(@deprecated("unused", "") v: c.Expr[Initialize[V]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Value[S, V]]
|
||||
): c.Expr[Setting[S]] =
|
||||
ContextUtil.selectMacroImpl[Setting[S]](c)((_, pos) => c.abort(pos, append1Migration))
|
||||
def fakeSettingAppend1Position[A1: Type, A2: Type](
|
||||
@deprecated("unused", "") v: Expr[Initialize[A2]]
|
||||
)(using
|
||||
qctx: Quotes
|
||||
): Expr[Setting[A1]] =
|
||||
import qctx.reflect.*
|
||||
report.errorAndAbort(TaskMacro.append1Migration)
|
||||
|
||||
def fakeSettingAppendNPosition[S: Type, V: Type](
|
||||
c: blackbox.Context
|
||||
)(@deprecated("unused", "") vs: c.Expr[Initialize[V]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Values[S, V]]
|
||||
): c.Expr[Setting[S]] =
|
||||
ContextUtil.selectMacroImpl[Setting[S]](c)((_, pos) => c.abort(pos, appendNMigration))
|
||||
def fakeSettingAppendNPosition[A1: Type, A2: Type](
|
||||
@deprecated("unused", "") vs: Expr[Initialize[A2]]
|
||||
)(using
|
||||
qctx: Quotes
|
||||
): Expr[Setting[A1]] =
|
||||
import qctx.reflect.*
|
||||
report.errorAndAbort(TaskMacro.appendNMigration)
|
||||
|
||||
def fakeItaskAssignPosition[A1: Type](c: blackbox.Context)(
|
||||
@deprecated("unused", "") app: c.Expr[Initialize[Task[A1]]]
|
||||
): c.Expr[Setting[Task[A1]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[A1]]](c)((_, pos) => c.abort(pos, assignMigration))
|
||||
def fakeItaskAssignPosition[A1: Type](
|
||||
@deprecated("unused", "") app: Expr[Initialize[Task[A1]]]
|
||||
)(using qctx: Quotes): Expr[Setting[Task[A1]]] =
|
||||
import qctx.reflect.*
|
||||
report.errorAndAbort(TaskMacro.assignMigration)
|
||||
|
||||
def fakeTaskAppend1Position[S: Type, V: Type](
|
||||
c: blackbox.Context
|
||||
)(@deprecated("unused", "") v: c.Expr[Initialize[Task[V]]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Value[S, V]]
|
||||
): c.Expr[Setting[Task[S]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[S]]](c)((_, pos) => c.abort(pos, append1Migration))
|
||||
def fakeTaskAppend1Position[A1: Type, A2: Type](
|
||||
@deprecated("unused", "") v: Expr[Initialize[Task[A2]]]
|
||||
)(using
|
||||
qctx: Quotes
|
||||
): Expr[Setting[Task[A2]]] =
|
||||
import qctx.reflect.*
|
||||
report.errorAndAbort(TaskMacro.append1Migration)
|
||||
|
||||
def fakeTaskAppendNPosition[S: Type, V: Type](
|
||||
c: blackbox.Context
|
||||
)(@deprecated("unused", "") vs: c.Expr[Initialize[Task[V]]])(
|
||||
@deprecated("unused", "") a: c.Expr[Append.Values[S, V]]
|
||||
): c.Expr[Setting[Task[S]]] =
|
||||
ContextUtil.selectMacroImpl[Setting[Task[S]]](c)((_, pos) => c.abort(pos, appendNMigration))
|
||||
def fakeTaskAppendNPosition[A1: Type, A2: Type](
|
||||
@deprecated("unused", "") vs: Expr[Initialize[Task[A2]]]
|
||||
)(using
|
||||
qctx: Quotes
|
||||
): Expr[Setting[Task[A1]]] =
|
||||
import qctx.reflect.*
|
||||
report.errorAndAbort(TaskMacro.appendNMigration)
|
||||
|
||||
/*
|
||||
// Implementations of <<= macro variations for tasks and settings.
|
||||
// These just get the source position of the call site.
|
||||
|
||||
def itaskAssignPosition[A1: Type](
|
||||
c: blackbox.Context
|
||||
def itaskAssignPosition[A1: Type](using
|
||||
qctx: Quotes
|
||||
)(app: c.Expr[Initialize[Task[A1]]]): c.Expr[Setting[Task[A1]]] =
|
||||
settingAssignPosition(c)(app)
|
||||
|
||||
def taskAssignPositionT[A1: Type](
|
||||
c: blackbox.Context
|
||||
def taskAssignPositionT[A1: Type](using
|
||||
qctx: Quotes
|
||||
)(app: c.Expr[Task[A1]]): c.Expr[Setting[Task[A1]]] =
|
||||
itaskAssignPosition(c)(c.universe.reify { Def.valueStrict(app.splice) })
|
||||
|
||||
def taskAssignPositionPure[A1: Type](
|
||||
c: blackbox.Context
|
||||
def taskAssignPositionPure[A1: Type](using
|
||||
qctx: Quotes
|
||||
)(app: c.Expr[A1]): c.Expr[Setting[Task[A1]]] =
|
||||
taskAssignPositionT(c)(c.universe.reify { TaskExtra.constant(app.splice) })
|
||||
|
||||
def taskTransformPosition[S: Type](
|
||||
c: blackbox.Context
|
||||
def taskTransformPosition[S: Type](using
|
||||
qctx: Quotes
|
||||
)(f: c.Expr[S => S]): c.Expr[Setting[Task[S]]] =
|
||||
c.Expr[Setting[Task[S]]](transformMacroImpl(c)(f.tree)(TransformInitName))
|
||||
|
||||
def settingTransformPosition[S: Type](
|
||||
c: blackbox.Context
|
||||
*/
|
||||
|
||||
def settingTransformPosition[A1: Type](rec: Expr[SettingKey[A1]], f: Expr[A1 => A1])(using
|
||||
qctx: Quotes
|
||||
): Expr[Setting[A1]] =
|
||||
'{
|
||||
$rec.transform($f, $sourcePosition)
|
||||
}
|
||||
|
||||
/*
|
||||
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 itaskTransformPosition[S: Type](
|
||||
c: blackbox.Context
|
||||
)(f: c.Expr[S => S]): c.Expr[Setting[S]] =
|
||||
c.Expr[Setting[S]](transformMacroImpl(c)(f.tree)(TransformInitName))
|
||||
|
||||
def settingAssignPure[A1: Type](c: blackbox.Context)(app: c.Expr[A1]): c.Expr[Setting[A1]] =
|
||||
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](
|
||||
c: blackbox.Context
|
||||
def settingAssignPosition[A1: Type](using
|
||||
qctx: Quotes
|
||||
)(app: c.Expr[Initialize[A1]]): c.Expr[Setting[A1]] =
|
||||
c.Expr[Setting[A1]](transformMacroImpl(c)(app.tree)(AssignInitName))
|
||||
|
||||
/** Implementation of := macro for tasks. */
|
||||
def inputTaskAssignMacroImpl[A1: Type](
|
||||
c: blackbox.Context
|
||||
def inputTaskAssignMacroImpl[A1: Type](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)
|
||||
|
|
@ -220,42 +234,42 @@ object TaskMacro:
|
|||
}
|
||||
|
||||
/** Implementation of += macro for tasks. */
|
||||
def taskAppend1Impl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
def taskAppend1Impl[A1: Type, U: Type](using
|
||||
qctx: Quotes
|
||||
)(v: c.Expr[U])(a: c.Expr[Append.Value[A1, U]]): c.Expr[Setting[Task[A1]]] = {
|
||||
val init = taskMacroImpl[U](c)(v)
|
||||
val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName)
|
||||
c.Expr[Setting[Task[A1]]](append)
|
||||
}
|
||||
*/
|
||||
|
||||
/** Implementation of += macro for settings. */
|
||||
def settingAppend1Impl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[U])(a: c.Expr[Append.Value[A1, U]]): c.Expr[Setting[A1]] = {
|
||||
import c.universe._
|
||||
val ttpe = c.weakTypeOf[A1]
|
||||
val typeArgs = ttpe.typeArgs
|
||||
v.tree.tpe match {
|
||||
// To allow Initialize[Task[A]] in the position of += RHS, we're going to call "taskValue" automatically.
|
||||
case tpe
|
||||
if typeArgs.nonEmpty && (typeArgs.head weak_<:< c.weakTypeOf[Task[_]])
|
||||
&& (tpe weak_<:< c.weakTypeOf[Initialize[_]]) =>
|
||||
c.macroApplication match {
|
||||
case Apply(Apply(TypeApply(Select(preT, _), _), _), _) =>
|
||||
val tree = Apply(
|
||||
TypeApply(Select(preT, TermName("+=").encodedName), TypeTree(typeArgs.head) :: Nil),
|
||||
Select(v.tree, TermName("taskValue").encodedName) :: Nil
|
||||
)
|
||||
c.Expr[Setting[A1]](tree)
|
||||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
case _ =>
|
||||
val init = SettingMacro.settingMacroImpl[U](c)(v)
|
||||
val append = appendMacroImpl(c)(init.tree, a.tree)(Append1InitName)
|
||||
c.Expr[Setting[A1]](append)
|
||||
}
|
||||
}
|
||||
def settingAppend1Impl[A1: Type, A2: Type](rec: Expr[SettingKey[A1]], v: Expr[A2])(using
|
||||
qctx: Quotes,
|
||||
): Expr[Setting[A1]] =
|
||||
import qctx.reflect.*
|
||||
// To allow Initialize[Task[A]] in the position of += RHS, we're going to call "taskValue" automatically.
|
||||
if TypeRepr.of[A2] <:< TypeRepr.of[Def.Initialize[Task[_]]] then
|
||||
Type.of[A2] match
|
||||
case '[Def.Initialize[Task[a]]] =>
|
||||
Expr.summon[Append.Value[A1, Task[a]]] match
|
||||
case Some(ev) =>
|
||||
val v2 = v.asExprOf[Def.Initialize[Task[a]]]
|
||||
'{
|
||||
$rec.+=($v2.taskValue)(using $ev)
|
||||
}
|
||||
case _ =>
|
||||
report.errorAndAbort(s"Append.Value[${Type.of[A1]}, ${Type.of[Task[a]]}] missing")
|
||||
else
|
||||
Expr.summon[Append.Value[A1, A2]] match
|
||||
case Some(ev) =>
|
||||
val init = SettingMacro.settingMacroImpl[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 tasks. */
|
||||
def taskAppendNImpl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
|
|
@ -264,113 +278,97 @@ object TaskMacro:
|
|||
val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName)
|
||||
c.Expr[Setting[Task[A1]]](append)
|
||||
}
|
||||
*/
|
||||
|
||||
/** Implementation of ++= macro for settings. */
|
||||
def settingAppendNImpl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(vs: c.Expr[U])(a: c.Expr[Append.Values[A1, U]]): c.Expr[Setting[A1]] = {
|
||||
val init = SettingMacro.settingMacroImpl[U](c)(vs)
|
||||
val append = appendMacroImpl(c)(init.tree, a.tree)(AppendNInitName)
|
||||
c.Expr[Setting[A1]](append)
|
||||
}
|
||||
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, U: Type](
|
||||
c: blackbox.Context
|
||||
def taskRemove1Impl[A1: Type, U: Type](using
|
||||
qctx: Quotes
|
||||
)(v: c.Expr[U])(r: c.Expr[Remove.Value[A1, U]]): c.Expr[Setting[Task[A1]]] = {
|
||||
val init = taskMacroImpl[U](c)(v)
|
||||
val remove = removeMacroImpl(c)(init.tree, r.tree)(Remove1InitName)
|
||||
c.Expr[Setting[Task[A1]]](remove)
|
||||
}
|
||||
*/
|
||||
|
||||
/** Implementation of -= macro for settings. */
|
||||
def settingRemove1Impl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(v: c.Expr[U])(r: c.Expr[Remove.Value[A1, U]]): c.Expr[Setting[A1]] = {
|
||||
val init = SettingMacro.settingMacroImpl[U](c)(v)
|
||||
val remove = removeMacroImpl(c)(init.tree, r.tree)(Remove1InitName)
|
||||
c.Expr[Setting[A1]](remove)
|
||||
}
|
||||
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, U: Type](
|
||||
c: blackbox.Context
|
||||
def taskRemoveNImpl[A1: Type, U: Type](using
|
||||
qctx: Quotes
|
||||
)(vs: c.Expr[U])(r: c.Expr[Remove.Values[A1, U]]): c.Expr[Setting[Task[A1]]] = {
|
||||
val init = taskMacroImpl[U](c)(vs)
|
||||
val remove = removeMacroImpl(c)(init.tree, r.tree)(RemoveNInitName)
|
||||
c.Expr[Setting[Task[A1]]](remove)
|
||||
}
|
||||
*/
|
||||
|
||||
/** Implementation of --= macro for settings. */
|
||||
def settingRemoveNImpl[A1: Type, U: Type](
|
||||
c: blackbox.Context
|
||||
)(vs: c.Expr[U])(r: c.Expr[Remove.Values[A1, U]]): c.Expr[Setting[A1]] = {
|
||||
val init = SettingMacro.settingMacroImpl[U](c)(vs)
|
||||
val remove = removeMacroImpl(c)(init.tree, r.tree)(RemoveNInitName)
|
||||
c.Expr[Setting[A1]](remove)
|
||||
}
|
||||
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[A1his] def appendMacroImpl(
|
||||
c: blackbox.Context
|
||||
)(init: c.Tree, append: c.Tree)(newName: String): c.Tree = {
|
||||
import c.universe._
|
||||
c.macroApplication match {
|
||||
case Apply(Apply(TypeApply(Select(preT, _), targs), _), _) =>
|
||||
Apply(
|
||||
Apply(
|
||||
TypeApply(Select(preT, TermName(newName).encodedName), targs),
|
||||
init :: sourcePosition(c).tree :: Nil
|
||||
),
|
||||
append :: Nil
|
||||
)
|
||||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
}
|
||||
|
||||
private[A1his] def removeMacroImpl(
|
||||
c: blackbox.Context
|
||||
)(init: c.Tree, remove: c.Tree)(newName: String): c.Tree = {
|
||||
import c.universe._
|
||||
c.macroApplication match {
|
||||
case Apply(Apply(TypeApply(Select(preT, _), targs), _), _) =>
|
||||
Apply(
|
||||
Apply(
|
||||
TypeApply(Select(preT, TermName(newName).encodedName), targs),
|
||||
init :: sourcePosition(c).tree :: Nil
|
||||
),
|
||||
remove :: Nil
|
||||
)
|
||||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
}
|
||||
|
||||
private[A1his] def transformMacroImpl(c: blackbox.Context)(init: c.Tree)(
|
||||
/*
|
||||
private[this] def transformMacroImpl[A](using qctx: Quotes)(init: Expr[A])(
|
||||
newName: String
|
||||
): c.Tree = {
|
||||
import c.universe._
|
||||
val target =
|
||||
c.macroApplication match {
|
||||
case Apply(Select(prefix, _), _) => prefix
|
||||
case x => ContextUtil.unexpectedTree(x)
|
||||
}
|
||||
): qctx.reflect.Term = {
|
||||
import qctx.reflect.*
|
||||
// val target =
|
||||
// c.macroApplication match {
|
||||
// case Apply(Select(prefix, _), _) => prefix
|
||||
// case x => ContextUtil.unexpectedTree(x)
|
||||
// }
|
||||
Apply.apply(
|
||||
Select(target, TermName(newName).encodedName),
|
||||
init :: sourcePosition(c).tree :: Nil
|
||||
Select(This, TermName(newName).encodedName),
|
||||
init.asTerm :: sourcePosition.asTerm :: Nil
|
||||
)
|
||||
}
|
||||
*/
|
||||
|
||||
private[A1his] def sourcePosition(c: blackbox.Context): c.Expr[SourcePosition] = {
|
||||
import c.universe.reify
|
||||
val pos = c.enclosingPosition
|
||||
if (!pos.isInstanceOf[UndefinedPosition] && pos.line >= 0 && pos.source != null) {
|
||||
val f = pos.source.file
|
||||
val name = constant[String](c, settingSource(c, f.path, f.name))
|
||||
val line = constant[Int](c, pos.line)
|
||||
reify { LinePosition(name.splice, line.splice) }
|
||||
} else reify { NoPosition }
|
||||
}
|
||||
private[this] def sourcePosition(using qctx: Quotes): Expr[SourcePosition] =
|
||||
import qctx.reflect.*
|
||||
val pos = Position.ofMacroExpansion
|
||||
if pos.startLine >= 0 && pos.sourceCode != None then
|
||||
val name = Expr(pos.sourceCode.get)
|
||||
val line = Expr(pos.startLine)
|
||||
'{ LinePosition($name, $line) }
|
||||
else '{ NoPosition }
|
||||
|
||||
private[A1his] def settingSource(c: blackbox.Context, path: String, name: String): String = {
|
||||
/*
|
||||
private[this] def settingSource(c: blackbox.Context, path: String, name: String): String = {
|
||||
@tailrec def inEmptyPackage(s: c.Symbol): Boolean = s != c.universe.NoSymbol && (
|
||||
s.owner == c.mirror.EmptyPackage || s.owner == c.mirror.EmptyPackageClass || inEmptyPackage(
|
||||
s.owner
|
||||
|
|
@ -383,7 +381,7 @@ object TaskMacro:
|
|||
}
|
||||
}
|
||||
|
||||
private[A1his] def constant[A1: c.TypeTag](c: blackbox.Context, t: T): c.Expr[A1] = {
|
||||
private[this] def constant[A1: c.TypeTag](c: blackbox.Context, t: T): c.Expr[A1] = {
|
||||
import c.universe._
|
||||
c.Expr[A1](Literal(Constant(t)))
|
||||
}
|
||||
|
|
@ -398,7 +396,7 @@ object TaskMacro:
|
|||
)(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[InputTask[A1]]] =
|
||||
inputTaskDynMacro0[A1](c)(t)
|
||||
|
||||
private[A1his] def inputTaskMacro0[A1: Type](
|
||||
private[this] def inputTaskMacro0[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[A1]): c.Expr[Initialize[InputTask[A1]]] =
|
||||
iInitializeMacro(c)(t) { et =>
|
||||
|
|
@ -408,7 +406,7 @@ object TaskMacro:
|
|||
c.universe.reify { InputTask.make(pt.splice) }
|
||||
}
|
||||
|
||||
private[A1his] def iInitializeMacro[M[_], T](c: blackbox.Context)(t: c.Expr[A1])(
|
||||
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
|
||||
|
|
@ -420,7 +418,7 @@ object TaskMacro:
|
|||
)
|
||||
}
|
||||
|
||||
private[A1his] def conditionInputTaskTree(c: blackbox.Context)(t: c.Tree): c.Tree = {
|
||||
private[this] def conditionInputTaskTree(c: blackbox.Context)(t: c.Tree): c.Tree = {
|
||||
import c.universe._
|
||||
import InputWrapper._
|
||||
def wrapInitTask[A1: Type](tree: Tree) = {
|
||||
|
|
@ -453,7 +451,7 @@ object TaskMacro:
|
|||
util.transformWrappers(t, (nme, tpe, tree, original) => expand(nme, tpe, tree))
|
||||
}
|
||||
|
||||
private[A1his] def iParserMacro[M[_], T](c: blackbox.Context)(t: c.Expr[A1])(
|
||||
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
|
||||
|
|
@ -463,7 +461,7 @@ object TaskMacro:
|
|||
)
|
||||
}
|
||||
|
||||
private[A1his] def iTaskMacro[A1: Type](
|
||||
private[this] def iTaskMacro[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[A1]): c.Expr[Task[A1]] =
|
||||
Instance
|
||||
|
|
@ -472,7 +470,7 @@ object TaskMacro:
|
|||
Instance.idTransform
|
||||
)
|
||||
|
||||
private[A1his] def inputTaskDynMacro0[A1: Type](
|
||||
private[this] def inputTaskDynMacro0[A1: Type](
|
||||
c: blackbox.Context
|
||||
)(t: c.Expr[Initialize[Task[A1]]]): c.Expr[Initialize[InputTask[A1]]] = {
|
||||
import c.universe.{ Apply => ApplyTree, _ }
|
||||
|
|
@ -554,7 +552,7 @@ object TaskMacro:
|
|||
inputTaskCreateFree(tag.tpe, init)
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
end TaskMacro
|
||||
|
||||
|
|
|
|||
|
|
@ -59,27 +59,29 @@ object Assign {
|
|||
/* def azy = sk.value
|
||||
|
||||
def azy2 = appmacro.Debug.checkWild(Def.task{ sk.value.size })
|
||||
*/
|
||||
|
||||
val settings = Seq(
|
||||
ak += z.value + (if(y.value) set.value else plain.value),
|
||||
ck := new File(ck.value, "asdf"),
|
||||
ak := sk.value.size,
|
||||
bk ++= Seq(z.value)
|
||||
)*/
|
||||
// ak += z.value + (if (y.value) set.value else plain.value),
|
||||
ck := new File(ck.value, "asdf"),
|
||||
ak := sk.value.size,
|
||||
// bk ++= Seq(z.value)
|
||||
)
|
||||
|
||||
val zz = Def.task {
|
||||
mk.value + tk.value + mk.value + tk.value + mk.value + tk.value + mk.value + tk.value + mk.value + tk.value + mk.value + tk.value
|
||||
}
|
||||
|
||||
// import DefaultParsers._
|
||||
// val p = Def.setting { name.value ~> Space ~> ID }
|
||||
// val is = Seq(
|
||||
// mk := 3,
|
||||
// name := "asdf",
|
||||
// tk := (math.random() * 1000).toInt,
|
||||
// isk := dummys.value.parsed // should not compile: cannot use a task to define the parser
|
||||
// // ik := { if( tsk.parsed.value == "blue") tk.value else mk.value }
|
||||
// )
|
||||
import DefaultParsers._
|
||||
val p = Def.setting { name.value ~> Space ~> ID }
|
||||
val is = Seq(
|
||||
mk := 3,
|
||||
name := "asdf",
|
||||
// name <<= name,
|
||||
tk := (math.random() * 1000).toInt,
|
||||
// isk := dummys.value.parsed, // should not compile: cannot use a task to define the parser
|
||||
// ik := { if (tsk.parsed.value == "blue") tk.value else mk.value }
|
||||
)
|
||||
|
||||
// val it1 = Def.inputTask {
|
||||
// tsk.parsed // "as" //dummy.value.parsed
|
||||
|
|
@ -126,6 +128,8 @@ object Assign {
|
|||
// seqSetting += "test4"
|
||||
|
||||
// listSetting := List("test1")
|
||||
// listSetting ++= List("test2")
|
||||
// listSetting += "test4"
|
||||
listSetting ++= List("test2")
|
||||
listSetting += "test4"
|
||||
|
||||
listSetting ~= { (xs) => xs }
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue