Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Target type abstract to allow overriding by different concrete implementations #2402

Merged
merged 18 commits into from
Apr 3, 2023
18 changes: 6 additions & 12 deletions main/core/src/mill/define/Router.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,14 @@ class Router(val ctx: blackbox.Context) extends mainargs.Macros(ctx) {
cases: (Type, Int, String)*
): Unit = {
for (m <- methods.toList) {
for ((tt, n, label) <- cases) {
if (
m.returnType <:< tt &&
m.paramLists.length != n
) {
c.abort(
cases
.find{case (tt, n, label) => m.returnType <:< tt}
.foreach{case (tt, n, label) =>
if (m.paramLists.length != n) c.abort(
m.pos,
s"$label definitions must have $n parameter list" + (if (n == 1) "" else "s")
)
}
}
}
}
val mapping = for {
Expand All @@ -59,11 +56,8 @@ class Router(val ctx: blackbox.Context) extends mainargs.Macros(ctx) {
overridesRoutes = {
assertParamListCounts(
methods,
(weakTypeOf[mill.define.Sources], 0, "`T.sources`"),
(weakTypeOf[mill.define.Input[_]], 0, "`T.input`"),
(weakTypeOf[mill.define.Persistent[_]], 0, "`T.persistent`"),
(weakTypeOf[mill.define.Target[_]], 0, "`T{...}`"),
(weakTypeOf[mill.define.Command[_]], 1, "`T.command`")
(weakTypeOf[mill.define.Command[_]], 1, "`T.command`"),
(weakTypeOf[mill.define.Target[_]], 0, "Target"),
)

for {
Expand Down
102 changes: 51 additions & 51 deletions main/core/src/mill/define/Task.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,22 @@ abstract class Task[+T] extends Task.Ops[T] with Applyable[Task, T] {

def asTarget: Option[Target[T]] = None
def asCommand: Option[Command[T]] = None
def asWorker: Option[Worker[T]] = None
def asWorker: Option[Target[T]] = None
def self: Task[T] = this
}

trait NamedTask[+T] extends Task[T] {
trait Target[+T] extends Task[T] {
def ctx: mill.define.Ctx
def label: String = ctx.segment match {
case Segment.Label(v) => v
case Segment.Cross(_) => throw new IllegalArgumentException(
"NamedTask only support a ctx with a Label segment, but found a Cross."
"Target only support a ctx with a Label segment, but found a Cross."
)
}
override def toString = ctx.segments.render
def isPrivate: Option[Boolean] = None
}
trait Target[+T] extends NamedTask[T] {
trait CachedTarget[+T] extends Target[T] {
override def asTarget: Option[Target[T]] = Some(this)
def readWrite: RW[_]
}
Expand Down Expand Up @@ -80,7 +80,7 @@ object Target extends Applicative.Applyer[Task, Task, Result, mill.api.Ctx] {

val lhs = Applicative.impl0[Task, T, mill.api.Ctx](c)(reify(Result.Success(t.splice)).tree)

mill.moduledefs.Cacher.impl0[TargetImpl[T]](c)(
mill.moduledefs.Cacher.impl0[Target[T]](c)(
reify(
new TargetImpl[T](
lhs.splice,
Expand Down Expand Up @@ -144,10 +144,10 @@ object Target extends Applicative.Applyer[Task, Task, Result, mill.api.Ctx] {
)
}

def sources(values: Result[os.Path]*)(implicit ctx: mill.define.Ctx): Sources = macro sourcesImpl1
def sources(values: Result[os.Path]*)(implicit ctx: mill.define.Ctx): Target[Seq[PathRef]] = macro sourcesImpl1

def sourcesImpl1(c: Context)(values: c.Expr[Result[os.Path]]*)(ctx: c.Expr[mill.define.Ctx])
: c.Expr[Sources] = {
: c.Expr[Target[Seq[PathRef]]] = {
import c.universe._
val wrapped =
for (value <- values.toList)
Expand All @@ -157,9 +157,9 @@ object Target extends Applicative.Applyer[Task, Task, Result, mill.api.Ctx] {

val taskIsPrivate = isPrivateTargetOption(c)

mill.moduledefs.Cacher.impl0[Sources](c)(
mill.moduledefs.Cacher.impl0[SourcesImpl](c)(
reify(
new Sources(
new SourcesImpl(
Target.sequence(c.Expr[List[Task[PathRef]]](q"_root_.scala.List(..$wrapped)").splice),
ctx.splice,
taskIsPrivate.splice
Expand All @@ -168,29 +168,29 @@ object Target extends Applicative.Applyer[Task, Task, Result, mill.api.Ctx] {
)
}

def sources(values: Result[Seq[PathRef]])(implicit ctx: mill.define.Ctx): Sources =
def sources(values: Result[Seq[PathRef]])(implicit ctx: mill.define.Ctx): Target[Seq[PathRef]] =
macro sourcesImpl2

def sourcesImpl2(c: Context)(values: c.Expr[Result[Seq[PathRef]]])(ctx: c.Expr[mill.define.Ctx])
: c.Expr[Sources] = {
: c.Expr[Target[Seq[PathRef]]] = {
import c.universe._

val taskIsPrivate = isPrivateTargetOption(c)

mill.moduledefs.Cacher.impl0[Sources](c)(
mill.moduledefs.Cacher.impl0[SourcesImpl](c)(
reify(
new Sources(
new SourcesImpl(
Applicative.impl0[Task, Seq[PathRef], mill.api.Ctx](c)(values.tree).splice,
ctx.splice,
taskIsPrivate.splice
)
)
)
}
def source(value: Result[os.Path])(implicit ctx: mill.define.Ctx): Source = macro sourceImpl1
def source(value: Result[os.Path])(implicit ctx: mill.define.Ctx): Target[PathRef] = macro sourceImpl1

def sourceImpl1(c: Context)(value: c.Expr[Result[os.Path]])(ctx: c.Expr[mill.define.Ctx])
: c.Expr[Source] = {
: c.Expr[Target[PathRef]] = {
import c.universe._

val wrapped =
Expand All @@ -200,9 +200,9 @@ object Target extends Applicative.Applyer[Task, Task, Result, mill.api.Ctx] {

val taskIsPrivate = isPrivateTargetOption(c)

mill.moduledefs.Cacher.impl0[Source](c)(
mill.moduledefs.Cacher.impl0[Target[PathRef]](c)(
reify(
new Source(
new SourceImpl(
wrapped.splice,
ctx.splice,
taskIsPrivate.splice
Expand All @@ -211,17 +211,17 @@ object Target extends Applicative.Applyer[Task, Task, Result, mill.api.Ctx] {
)
}

def source(value: Result[PathRef])(implicit ctx: mill.define.Ctx): Source = macro sourceImpl2
def source(value: Result[PathRef])(implicit ctx: mill.define.Ctx): Target[PathRef] = macro sourceImpl2

def sourceImpl2(c: Context)(value: c.Expr[Result[PathRef]])(ctx: c.Expr[mill.define.Ctx])
: c.Expr[Source] = {
: c.Expr[Target[PathRef]] = {
import c.universe._

val taskIsPrivate = isPrivateTargetOption(c)

mill.moduledefs.Cacher.impl0[Source](c)(
mill.moduledefs.Cacher.impl0[Target[PathRef]](c)(
reify(
new Source(
new SourceImpl(
Applicative.impl0[Task, PathRef, mill.api.Ctx](c)(value.tree).splice,
ctx.splice,
taskIsPrivate.splice
Expand All @@ -232,20 +232,20 @@ object Target extends Applicative.Applyer[Task, Task, Result, mill.api.Ctx] {
def input[T](value: Result[T])(implicit
w: upickle.default.Writer[T],
ctx: mill.define.Ctx
): Input[T] =
): Target[T] =
macro inputImpl[T]

def inputImpl[T: c.WeakTypeTag](c: Context)(value: c.Expr[T])(
w: c.Expr[upickle.default.Writer[T]],
ctx: c.Expr[mill.define.Ctx]
): c.Expr[Input[T]] = {
): c.Expr[Target[T]] = {
import c.universe._

val taskIsPrivate = isPrivateTargetOption(c)

mill.moduledefs.Cacher.impl0[Input[T]](c)(
mill.moduledefs.Cacher.impl0[InputImpl[T]](c)(
reify(
new Input[T](
new InputImpl[T](
Applicative.impl[Task, T, mill.api.Ctx](c)(value).splice,
ctx.splice,
w.splice,
Expand Down Expand Up @@ -307,31 +307,31 @@ object Target extends Applicative.Applyer[Task, Task, Result, mill.api.Ctx] {
)
}

def worker[T](t: Task[T])(implicit ctx: mill.define.Ctx): Worker[T] = macro workerImpl1[T]
def worker[T](t: Task[T])(implicit ctx: mill.define.Ctx): Target[T] = macro workerImpl1[T]

def workerImpl1[T: c.WeakTypeTag](c: Context)(t: c.Expr[Task[T]])(ctx: c.Expr[mill.define.Ctx])
: c.Expr[Worker[T]] = {
: c.Expr[Target[T]] = {
import c.universe._

val taskIsPrivate = isPrivateTargetOption(c)

mill.moduledefs.Cacher.impl0[Worker[T]](c)(
mill.moduledefs.Cacher.impl0[Target[T]](c)(
reify(
new Worker[T](t.splice, ctx.splice, taskIsPrivate.splice)
new WorkerImpl[T](t.splice, ctx.splice, taskIsPrivate.splice)
)
)
}
def worker[T](t: Result[T])(implicit ctx: mill.define.Ctx): Worker[T] = macro workerImpl2[T]
def worker[T](t: Result[T])(implicit ctx: mill.define.Ctx): Target[T] = macro workerImpl2[T]

def workerImpl2[T: c.WeakTypeTag](c: Context)(t: c.Expr[T])(ctx: c.Expr[mill.define.Ctx])
: c.Expr[Worker[T]] = {
: c.Expr[Target[T]] = {
import c.universe._

val taskIsPrivate = isPrivateTargetOption(c)

mill.moduledefs.Cacher.impl0[Worker[T]](c)(
mill.moduledefs.Cacher.impl0[Target[T]](c)(
reify(
new Worker[T](
new WorkerImpl[T](
Applicative.impl[Task, T, mill.api.Ctx](c)(t).splice,
ctx.splice,
taskIsPrivate.splice
Expand All @@ -342,20 +342,20 @@ object Target extends Applicative.Applyer[Task, Task, Result, mill.api.Ctx] {

def task[T](t: Result[T]): Task[T] = macro Applicative.impl[Task, T, mill.api.Ctx]

def persistent[T](t: Result[T])(implicit rw: RW[T], ctx: mill.define.Ctx): Persistent[T] =
def persistent[T](t: Result[T])(implicit rw: RW[T], ctx: mill.define.Ctx): Target[T] =
macro persistentImpl[T]

def persistentImpl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T])(
rw: c.Expr[RW[T]],
ctx: c.Expr[mill.define.Ctx]
): c.Expr[Persistent[T]] = {
): c.Expr[PersistentImpl[T]] = {
import c.universe._

val taskIsPrivate = isPrivateTargetOption(c)

mill.moduledefs.Cacher.impl0[Persistent[T]](c)(
mill.moduledefs.Cacher.impl0[PersistentImpl[T]](c)(
reify(
new Persistent[T](
new PersistentImpl[T](
Applicative.impl[Task, T, mill.api.Ctx](c)(t).splice,
ctx.splice,
rw.splice,
Expand All @@ -375,11 +375,11 @@ object Target extends Applicative.Applyer[Task, Task, Result, mill.api.Ctx] {
}
}

abstract class NamedTaskImpl[+T](
abstract class TargetImplBase[+T](
ctx0: mill.define.Ctx,
t: Task[T],
override val isPrivate: Option[Boolean]
) extends NamedTask[T] {
) extends Target[T] {
def evaluate(args: mill.api.Ctx) = args[T](0)
val ctx = ctx0.withSegments(segments = ctx0.segments ++ Seq(ctx0.segment))
val inputs = Seq(t)
Expand All @@ -390,26 +390,26 @@ class TargetImpl[+T](
ctx0: mill.define.Ctx,
override val readWrite: RW[_],
isPrivate: Option[Boolean]
) extends NamedTaskImpl[T](ctx0, t, isPrivate)
with Target[T] {}
) extends TargetImplBase[T](ctx0, t, isPrivate)
with CachedTarget[T] {}

class Command[+T](
t: Task[T],
ctx0: mill.define.Ctx,
val writer: W[_],
val cls: Class[_],
isPrivate: Option[Boolean]
) extends NamedTaskImpl[T](ctx0, t, isPrivate) {
) extends TargetImplBase[T](ctx0, t, isPrivate) {
override def asCommand = Some(this)
}

class Worker[+T](t: Task[T], ctx0: mill.define.Ctx, isPrivate: Option[Boolean])
extends NamedTaskImpl[T](ctx0, t, isPrivate) {
class WorkerImpl[+T](t: Task[T], ctx0: mill.define.Ctx, isPrivate: Option[Boolean])
extends TargetImplBase[T](ctx0, t, isPrivate) {
override def flushDest = false
override def asWorker = Some(this)
}

class Persistent[+T](
class PersistentImpl[+T](
t: Task[T],
ctx0: mill.define.Ctx,
readWrite: RW[_],
Expand All @@ -419,25 +419,25 @@ class Persistent[+T](
override def flushDest = false
}

class Input[T](
class InputImpl[T](
t: Task[T],
ctx0: mill.define.Ctx,
val writer: upickle.default.Writer[_],
isPrivate: Option[Boolean]
) extends NamedTaskImpl[T](ctx0, t, isPrivate) {
) extends TargetImplBase[T](ctx0, t, isPrivate) {
override def sideHash = util.Random.nextInt()
}

class Sources(t: Task[Seq[PathRef]], ctx0: mill.define.Ctx, isPrivate: Option[Boolean])
extends Input[Seq[PathRef]](
class SourcesImpl(t: Task[Seq[PathRef]], ctx0: mill.define.Ctx, isPrivate: Option[Boolean])
extends InputImpl[Seq[PathRef]](
t,
ctx0,
upickle.default.SeqLikeWriter[Seq, PathRef],
isPrivate
)

class Source(t: Task[PathRef], ctx0: mill.define.Ctx, isPrivate: Option[Boolean])
extends Input[PathRef](
class SourceImpl(t: Task[PathRef], ctx0: mill.define.Ctx, isPrivate: Option[Boolean])
extends InputImpl[PathRef](
t,
ctx0,
PathRef.jsonFormatter,
Expand Down
8 changes: 8 additions & 0 deletions main/core/src/mill/define/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package mill
package object define{
type Source = define.Target[mill.api.PathRef]
type Sources = define.Target[Seq[mill.api.PathRef]]
type Input[T] = define.Target[T]
type Persistent[T] = define.Target[T]
type Worker[T] = define.Target[T]
}
Loading