summaryrefslogtreecommitdiff
path: root/core/src/main
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-01-07 22:38:17 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-01-07 22:38:17 -0800
commit4fd5f8cdfdc924bff2f4fbc6b5d7072d530fa531 (patch)
tree6e7c85efc2b3e59f56e1d207a42dda459243982b /core/src/main
parenta30db9485048e8d6e260d5d506894bd6b41f1d72 (diff)
downloadmill-4fd5f8cdfdc924bff2f4fbc6b5d7072d530fa531.tar.gz
mill-4fd5f8cdfdc924bff2f4fbc6b5d7072d530fa531.tar.bz2
mill-4fd5f8cdfdc924bff2f4fbc6b5d7072d530fa531.zip
Generate the `Segments` list at definition time rather than discovery time, by propagating implicits throughout the tree of nested `mill.Module`s
This currently adds some annoying boilerplate to the definition of cross/abstract modules, which can probably be removed using Macros. The `Segments` mapping generated by discovery is still present and used in a few places, though it will be removed
Diffstat (limited to 'core/src/main')
-rw-r--r--core/src/main/scala/mill/define/Cross.scala57
-rw-r--r--core/src/main/scala/mill/define/Module.scala59
-rw-r--r--core/src/main/scala/mill/define/Task.scala201
-rw-r--r--core/src/main/scala/mill/discover/Discovered.scala11
-rw-r--r--core/src/main/scala/mill/discover/Mirror.scala16
-rw-r--r--core/src/main/scala/mill/eval/Evaluator.scala25
-rw-r--r--core/src/main/scala/mill/main/ReplApplyHandler.scala6
-rw-r--r--core/src/main/scala/mill/main/Resolve.scala18
-rw-r--r--core/src/main/scala/mill/main/RunScript.scala22
9 files changed, 184 insertions, 231 deletions
diff --git a/core/src/main/scala/mill/define/Cross.scala b/core/src/main/scala/mill/define/Cross.scala
index 26eef933..4d68ee62 100644
--- a/core/src/main/scala/mill/define/Cross.scala
+++ b/core/src/main/scala/mill/define/Cross.scala
@@ -26,14 +26,53 @@ object Cross{
def apply[T](t: T*) = new Cross(t.map(i => List(i) -> i).toList)
}
-class CrossModule[T, V](constructor: T => V, cases: T*)
- (implicit e: sourcecode.Enclosing, l: sourcecode.Line)
-extends Cross[V](cases.toList.map(x => (List(x), constructor(x))))
+class CrossModule[T, V](constructor: (T, Module.Ctx) => V, cases: T*)
+ (implicit ctx: Module.Ctx)
+extends Cross[V]({
+ cases.toList.map(x =>
+ (
+ List(x),
+ constructor(
+ x,
+ ctx.copy(
+ segments0 = Segments(ctx.segments0.value :+ ctx.segment),
+ segment = Segment.Cross(List(x))
+ )
+ )
+ )
+ )
+})
-class CrossModule2[T1, T2, V](constructor: (T1, T2) => V, cases: (T1, T2)*)
- (implicit e: sourcecode.Enclosing, l: sourcecode.Line)
-extends Cross[V](cases.toList.map(x => (List(x._2, x._1), constructor(x._1, x._2))))
+class CrossModule2[T1, T2, V](constructor: (T1, T2, Module.Ctx) => V, cases: (T1, T2)*)
+ (implicit ctx: Module.Ctx)
+extends Cross[V](
+ cases.toList.map(x =>
+ (
+ List(x._2, x._1),
+ constructor(
+ x._1, x._2,
+ ctx.copy(
+ segments0 = Segments(ctx.segments0.value :+ ctx.segment),
+ segment = Segment.Cross(List(x._2, x._1))
+ )
+ )
+ )
+ )
+)
-class CrossModule3[T1, T2, T3, V](constructor: (T1, T2, T3) => V, cases: (T1, T2, T3)*)
- (implicit e: sourcecode.Enclosing, l: sourcecode.Line)
-extends Cross[V](cases.toList.map(x => (List(x._3, x._2, x._1), constructor(x._1, x._2, x._3)))) \ No newline at end of file
+class CrossModule3[T1, T2, T3, V](constructor: (T1, T2, T3, Module.Ctx) => V, cases: (T1, T2, T3)*)
+ (implicit ctx: Module.Ctx)
+extends Cross[V](
+ cases.toList.map(x =>
+ (
+ List(x._3, x._2, x._1),
+ constructor(
+ x._1, x._2, x._3,
+ ctx.copy(
+ segments0 = Segments(ctx.segments0.value :+ ctx.segment),
+ segment = Segment.Cross(List(x._3, x._2, x._1))
+ )
+ )
+ )
+ )
+) \ No newline at end of file
diff --git a/core/src/main/scala/mill/define/Module.scala b/core/src/main/scala/mill/define/Module.scala
index b2e90a6e..c5837278 100644
--- a/core/src/main/scala/mill/define/Module.scala
+++ b/core/src/main/scala/mill/define/Module.scala
@@ -1,42 +1,71 @@
package mill.define
+import ammonite.main.Router.Overrides
import ammonite.ops.Path
+import scala.annotation.implicitNotFound
+
+sealed trait Segment
+object Segment{
+ case class Label(value: String) extends Segment
+ case class Cross(value: Seq[Any]) extends Segment
+}
+
case class BasePath(value: Path)
+case class Segments(value: Seq[Segment])
/**
* `Module` is a class meant to be extended by `trait`s *only*, in order to
* propagate the implicit parameters forward to the final concrete
* instantiation site so they can capture the enclosing/line information of
* the concrete instance.
*/
-class Module(implicit ctx: Module.Ctx) extends mill.moduledefs.Cacher{
+class Module(implicit ctx0: Module.Ctx) extends mill.moduledefs.Cacher{
+ val ctx = ctx0
// Ensure we do not propagate the implicit parameters as implicits within
// the body of any inheriting class/trait/objects, as it would screw up any
// one else trying to use sourcecode.{Enclosing,Line} to capture debug info
- val millModuleEnclosing = ctx.millModuleEnclosing0
- val millModuleLine = ctx.millModuleLine0
- def basePath: Path = ctx.millModuleBasePath0.value / ctx.millName0.value
+ val millModuleEnclosing = ctx.enclosing
+ val millModuleLine = ctx.lineNum
+ def basePath: Path = ctx.basePath / (ctx.segment match{
+ case Segment.Label(s) => List(s)
+ case Segment.Cross(vs) => vs.map(_.toString)
+ })
implicit def millModuleBasePath: BasePath = BasePath(basePath)
+ implicit def millModuleSegments: Segments = {
+ Segments(ctx.segments0.value :+ ctx.segment)
+ }
}
object Module{
- case class Ctx(millModuleEnclosing0: sourcecode.Enclosing,
- millModuleLine0: sourcecode.Line,
- millName0: sourcecode.Name,
- millModuleBasePath0: BasePath)
+ @implicitNotFound("Modules, Targets and Commands can only be defined within a mill Module")
+ case class Ctx(enclosing: String,
+ lineNum: Int,
+ segment: Segment,
+ basePath: Path,
+ segments0: Segments,
+ overrides: Int){
+ def segments = Segments(segments0.value.drop(1))
+ }
object Ctx{
implicit def make(implicit millModuleEnclosing0: sourcecode.Enclosing,
millModuleLine0: sourcecode.Line,
millName0: sourcecode.Name,
- millModuleBasePath0: BasePath): Ctx = Ctx(
- millModuleEnclosing0,
- millModuleLine0,
- millName0,
- millModuleBasePath0
+ millModuleBasePath0: BasePath,
+ segments0: Segments,
+ overrides0: Overrides): Ctx = Ctx(
+ millModuleEnclosing0.value,
+ millModuleLine0.value,
+ Segment.Label(millName0.value),
+ millModuleBasePath0.value,
+ segments0,
+ overrides0.value
)
}
}
class BaseModule(basePath: Path)
(implicit millModuleEnclosing0: sourcecode.Enclosing,
millModuleLine0: sourcecode.Line,
- millName0: sourcecode.Name)
- extends Module()(Module.Ctx.make(implicitly, implicitly, implicitly, BasePath(basePath))) \ No newline at end of file
+ millName0: sourcecode.Name,
+ overrides0: Overrides)
+ extends Module()(
+ Module.Ctx.make(implicitly, implicitly, implicitly, BasePath(basePath), Segments(Nil), implicitly)
+ ) \ No newline at end of file
diff --git a/core/src/main/scala/mill/define/Task.scala b/core/src/main/scala/mill/define/Task.scala
index 34e56907..96fdbb8e 100644
--- a/core/src/main/scala/mill/define/Task.scala
+++ b/core/src/main/scala/mill/define/Task.scala
@@ -1,6 +1,5 @@
package mill.define
-import ammonite.main.Router.Overrides
import mill.define.Applicative.Applyable
import mill.eval.{PathRef, Result}
import mill.util.Ctx
@@ -35,14 +34,10 @@ abstract class Task[+T] extends Task.Ops[T] with Applyable[Task, T]{
}
trait NamedTask[+T] extends Task[T]{
- def owner: Module
- def name: String
- def overrides: Int
+ def ctx: Module.Ctx
}
trait Target[+T] extends NamedTask[T]{
override def asTarget = Some(this)
- def enclosing: String
- def lineNum: Int
def readWrite: RW[_]
}
@@ -51,34 +46,19 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
implicit def apply[T](t: T)
(implicit r: R[T],
w: W[T],
- e: sourcecode.Enclosing,
- l: sourcecode.Line,
- n: sourcecode.Name,
- cl: Caller[Module],
- o: Overrides): Target[T] = macro targetImpl[T]
+ ctx: Module.Ctx): Target[T] = macro targetImpl[T]
def targetImpl[T: c.WeakTypeTag](c: Context)
(t: c.Expr[T])
(r: c.Expr[R[T]],
w: c.Expr[W[T]],
- e: c.Expr[sourcecode.Enclosing],
- l: c.Expr[sourcecode.Line],
- n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[Module]],
- o: c.Expr[Overrides]): c.Expr[Target[T]] = {
+ ctx: c.Expr[Module.Ctx]): c.Expr[Target[T]] = {
import c.universe._
val lhs = Applicative.impl0[Task, T, Ctx](c)(reify(Result.Success(t.splice)).tree)
mill.moduledefs.Cacher.impl0[TargetImpl[T]](c)(
reify(
- new TargetImpl[T](
- lhs.splice,
- e.splice.value,
- l.splice.value,
- cl.splice.value,
- n.splice.value,
- upickle.default.ReadWriter(w.splice.write, r.splice.read), o.splice.value
- )
+ new TargetImpl[T](lhs.splice, ctx.splice, RW(w.splice.write, r.splice.read))
)
)
}
@@ -86,32 +66,20 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
implicit def apply[T](t: Result[T])
(implicit r: R[T],
w: W[T],
- e: sourcecode.Enclosing,
- l: sourcecode.Line,
- n: sourcecode.Name,
- cl: Caller[Module],
- o: Overrides): Target[T] = macro targetResultImpl[T]
+ ctx: Module.Ctx): Target[T] = macro targetResultImpl[T]
def targetResultImpl[T: c.WeakTypeTag](c: Context)
(t: c.Expr[Result[T]])
(r: c.Expr[R[T]],
w: c.Expr[W[T]],
- e: c.Expr[sourcecode.Enclosing],
- l: c.Expr[sourcecode.Line],
- n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[Module]],
- o: c.Expr[Overrides]): c.Expr[Target[T]] = {
+ ctx: c.Expr[Module.Ctx]): c.Expr[Target[T]] = {
import c.universe._
mill.moduledefs.Cacher.impl0[Target[T]](c)(
reify(
new TargetImpl[T](
Applicative.impl0[Task, T, Ctx](c)(t.tree).splice,
- e.splice.value,
- l.splice.value,
- cl.splice.value,
- n.splice.value,
- upickle.default.ReadWriter(w.splice.write, r.splice.read),
- o.splice.value
+ ctx.splice,
+ RW(w.splice.write, r.splice.read)
)
)
)
@@ -120,62 +88,31 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
def apply[T](t: Task[T])
(implicit r: R[T],
w: W[T],
- e: sourcecode.Enclosing,
- l: sourcecode.Line,
- n: sourcecode.Name,
- cl: Caller[Module],
- o: Overrides): Target[T] = macro targetTaskImpl[T]
+ ctx: Module.Ctx): Target[T] = macro targetTaskImpl[T]
def targetTaskImpl[T: c.WeakTypeTag](c: Context)
(t: c.Expr[Task[T]])
(r: c.Expr[R[T]],
w: c.Expr[W[T]],
- e: c.Expr[sourcecode.Enclosing],
- l: c.Expr[sourcecode.Line],
- n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[Module]],
- o: c.Expr[Overrides]): c.Expr[Target[T]] = {
+ ctx: c.Expr[Module.Ctx]): c.Expr[Target[T]] = {
import c.universe._
mill.moduledefs.Cacher.impl0[Target[T]](c)(
reify(
- new TargetImpl[T](
- t.splice,
- e.splice.value,
- l.splice.value,
- cl.splice.value,
- n.splice.value,
- upickle.default.ReadWriter(w.splice.write, r.splice.read),
- o.splice.value
- )
+ new TargetImpl[T](t.splice, ctx.splice, RW(w.splice.write, r.splice.read))
)
)
}
- def command[T](t: Result[T])
- (implicit w: W[T],
- e: sourcecode.Enclosing,
- n: sourcecode.Name,
- cl: Caller[Module],
- o: Overrides): Command[T] = macro commandImpl[T]
-
def source(value: Result[ammonite.ops.Path])
(implicit r: R[PathRef],
w: W[PathRef],
- e: sourcecode.Enclosing,
- l: sourcecode.Line,
- n: sourcecode.Name,
- cl: Caller[Module],
- o: Overrides): Input[PathRef] = macro sourceImpl
+ ctx: Module.Ctx): Input[PathRef] = macro sourceImpl
def sourceImpl(c: Context)
(value: c.Expr[Result[ammonite.ops.Path]])
(r: c.Expr[R[PathRef]],
w: c.Expr[W[PathRef]],
- e: c.Expr[sourcecode.Enclosing],
- l: c.Expr[sourcecode.Line],
- n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[Module]],
- o: c.Expr[Overrides]): c.Expr[Input[PathRef]] = {
+ ctx: c.Expr[Module.Ctx]): c.Expr[Input[PathRef]] = {
import c.universe._
val wrapped: c.Expr[Result[PathRef]] = reify(value.splice match{
case Result.Success(p) => Result.Success(PathRef(p))
@@ -185,12 +122,8 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
reify(
new Input[PathRef](
Applicative.impl0[Task, PathRef, Ctx](c)(wrapped.tree).splice,
- e.splice.value,
- l.splice.value,
- cl.splice.value,
- n.splice.value,
- upickle.default.ReadWriter(w.splice.write, r.splice.read),
- o.splice.value
+ ctx.splice,
+ RW(w.splice.write, r.splice.read),
)
)
)
@@ -199,62 +132,41 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
def input[T](value: Result[T])
(implicit r: R[T],
w: W[T],
- e: sourcecode.Enclosing,
- l: sourcecode.Line,
- n: sourcecode.Name,
- cl: Caller[Module],
- o: Overrides): Input[T] = macro inputImpl[T]
+ ctx: Module.Ctx): Input[T] = macro inputImpl[T]
def inputImpl[T: c.WeakTypeTag](c: Context)
(value: c.Expr[T])
(r: c.Expr[R[T]],
w: c.Expr[W[T]],
- e: c.Expr[sourcecode.Enclosing],
- l: c.Expr[sourcecode.Line],
- n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[Module]],
- o: c.Expr[Overrides]): c.Expr[Input[T]] = {
+ ctx: c.Expr[Module.Ctx]): c.Expr[Input[T]] = {
import c.universe._
mill.moduledefs.Cacher.impl0[Input[T]](c)(
reify(
new Input[T](
Applicative.impl[Task, T, Ctx](c)(value).splice,
- e.splice.value,
- l.splice.value,
- cl.splice.value,
- n.splice.value,
- upickle.default.ReadWriter(w.splice.write, r.splice.read),
- o.splice.value
+ ctx.splice,
+ RW(w.splice.write, r.splice.read)
)
)
)
}
def command[T](t: Task[T])
- (implicit c: Caller[Module],
- e: sourcecode.Enclosing,
- n: sourcecode.Name,
- w: W[T],
- o: Overrides): Command[T] = new Command(t, e.value, c.value, n.value, w, o.value)
+ (implicit ctx: Module.Ctx,
+ w: W[T]): Command[T] = new Command(t, ctx, w)
+
+ def command[T](t: Result[T])
+ (implicit w: W[T],
+ ctx: Module.Ctx): Command[T] = macro commandImpl[T]
def commandImpl[T: c.WeakTypeTag](c: Context)
(t: c.Expr[T])
(w: c.Expr[W[T]],
- e: c.Expr[sourcecode.Enclosing],
- n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[Module]],
- o: c.Expr[Overrides]): c.Expr[Command[T]] = {
+ ctx: c.Expr[Module.Ctx]): c.Expr[Command[T]] = {
import c.universe._
reify(
- new Command[T](
- Applicative.impl[Task, T, Ctx](c)(t).splice,
- e.splice.value,
- cl.splice.value,
- n.splice.value,
- w.splice,
- o.splice.value
- )
+ new Command[T](Applicative.impl[Task, T, Ctx](c)(t).splice, ctx.splice, w.splice)
)
}
@@ -262,21 +174,13 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
def persistent[T](t: Result[T])(implicit r: R[T],
w: W[T],
- e: sourcecode.Enclosing,
- l: sourcecode.Line,
- n: sourcecode.Name,
- cl: Caller[Module],
- o: Overrides): Target[T] = macro persistentImpl[T]
+ ctx: Module.Ctx): Target[T] = macro persistentImpl[T]
def persistentImpl[T: c.WeakTypeTag](c: Context)
(t: c.Expr[T])
(r: c.Expr[R[T]],
w: c.Expr[W[T]],
- e: c.Expr[sourcecode.Enclosing],
- l: c.Expr[sourcecode.Line],
- n: c.Expr[sourcecode.Name],
- cl: c.Expr[Caller[Module]],
- o: c.Expr[Overrides]): c.Expr[Persistent[T]] = {
+ ctx: c.Expr[Module.Ctx]): c.Expr[Persistent[T]] = {
import c.universe._
@@ -284,12 +188,8 @@ object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Resul
reify(
new Persistent[T](
Applicative.impl[Task, T, Ctx](c)(t).splice,
- e.splice.value,
- l.splice.value,
- cl.splice.value,
- n.splice.value,
- upickle.default.ReadWriter(w.splice.write, r.splice.read),
- o.splice.value
+ ctx.splice,
+ RW(w.splice.write, r.splice.read)
)
)
)
@@ -319,44 +219,33 @@ object Caller {
}
class TargetImpl[+T](t: Task[T],
- val enclosing: String,
- val lineNum: Int,
- val owner: Module,
- val name: String,
- val readWrite: RW[_],
- val overrides: Int) extends Target[T] {
+ ctx0: Module.Ctx,
+ val readWrite: RW[_]) extends Target[T] {
+ val ctx = ctx0.copy(segments0 = Segments(ctx0.segments0.value :+ ctx0.segment))
val inputs = Seq(t)
def evaluate(args: Ctx) = args[T](0)
- override def toString = enclosing + "@" + Integer.toHexString(System.identityHashCode(this))
+ override def toString = ctx.enclosing + "@" + Integer.toHexString(System.identityHashCode(this))
}
class Command[+T](t: Task[T],
- val enclosing: String,
- val owner: Module,
- val name: String,
- val writer: W[_],
- val overrides: Int) extends NamedTask[T] {
+ ctx0: Module.Ctx,
+ val writer: W[_]) extends NamedTask[T] {
+ val ctx = ctx0.copy(segments0 = Segments(ctx0.segments0.value :+ ctx0.segment))
val inputs = Seq(t)
def evaluate(args: Ctx) = args[T](0)
override def asCommand = Some(this)
}
class Persistent[+T](t: Task[T],
- enclosing: String,
- lineNum: Int,
- owner: Module,
- name: String,
- readWrite: RW[_],
- overrides: Int)
- extends TargetImpl[T](t, enclosing, lineNum, owner, name, readWrite, overrides) {
+ ctx0: Module.Ctx,
+ readWrite: RW[_])
+ extends TargetImpl[T](t, ctx0, readWrite) {
+
override def flushDest = false
override def asPersistent = Some(this)
}
class Input[T](t: Task[T],
- val enclosing: String,
- val lineNum: Int,
- val owner: Module,
- val name: String,
- val readWrite: RW[_],
- val overrides: Int) extends Target[T]{
+ ctx0: Module.Ctx,
+ val readWrite: RW[_]) extends Target[T]{
+ val ctx = ctx0.copy(segments0 = Segments(ctx0.segments0.value :+ ctx0.segment))
val inputs = Seq(t)
def evaluate(args: Ctx) = args[T](0)
override def sideHash = util.Random.nextInt()
diff --git a/core/src/main/scala/mill/discover/Discovered.scala b/core/src/main/scala/mill/discover/Discovered.scala
index 44584137..74312f91 100644
--- a/core/src/main/scala/mill/discover/Discovered.scala
+++ b/core/src/main/scala/mill/discover/Discovered.scala
@@ -1,10 +1,9 @@
package mill.discover
-import mill.define.Module
-import mill.define.{Cross, Target, Task}
+import mill.define._
import ammonite.main.Router
import ammonite.main.Router.EntryPoint
-import mill.discover.Mirror.{Segment, TargetPoint}
+import mill.discover.Mirror.TargetPoint
import mill.util.Ctx.Loader
import scala.language.experimental.macros
@@ -27,7 +26,7 @@ object Discovered {
val modulesToPaths = Mirror.traverse(base, mirror){ (mirror, segmentsRev) =>
val resolvedNode = mirror.node(
base,
- segmentsRev.reverse.map{case Mirror.Segment.Cross(vs) => vs.toList case _ => Nil}.toList
+ segmentsRev.reverse.map{case Segment.Cross(vs) => vs.toList case _ => Nil}.toList
)
Seq(resolvedNode -> segmentsRev.reverse)
}.toMap
@@ -35,7 +34,7 @@ object Discovered {
val modulesToMirrors = Mirror.traverse[T, T, (Any, Mirror[_, _])](base, mirror){ (mirror, segmentsRev) =>
val resolvedNode = mirror.node(
base,
- segmentsRev.reverse.map{case Mirror.Segment.Cross(vs) => vs.toList case _ => Nil}.toList
+ segmentsRev.reverse.map{case Segment.Cross(vs) => vs.toList case _ => Nil}.toList
)
Seq(resolvedNode -> mirror)
}.toMap
@@ -43,7 +42,7 @@ object Discovered {
val targetsToSegments = Mirror.traverse(base, mirror){ (mirror, segmentsRev) =>
val resolvedNode = mirror.node(
base,
- segmentsRev.reverse.map{case Mirror.Segment.Cross(vs) => vs.toList case _ => Nil}.toList
+ segmentsRev.reverse.map{case Segment.Cross(vs) => vs.toList case _ => Nil}.toList
)
for(target <- mirror.targets) yield {
target.asInstanceOf[TargetPoint[Any, Any]].run(resolvedNode) -> (segmentsRev.reverse :+ Segment.Label(target.label))
diff --git a/core/src/main/scala/mill/discover/Mirror.scala b/core/src/main/scala/mill/discover/Mirror.scala
index 63b6900b..3443535e 100644
--- a/core/src/main/scala/mill/discover/Mirror.scala
+++ b/core/src/main/scala/mill/discover/Mirror.scala
@@ -1,6 +1,6 @@
package mill.discover
-import mill.define.{Target, Task}
+import mill.define.{Segment, Target, Task}
import ammonite.main.Router.EntryPoint
import scala.language.experimental.macros
@@ -20,21 +20,17 @@ case class Mirror[-T, V](node: (T, List[List[Any]]) => V,
crossChildren: Option[(V => List[List[Any]], Mirror[T, _])])
object Mirror{
- def renderSelector(selector: Seq[Mirror.Segment]) = selector.toList match {
+ def renderSelector(selector: Seq[Segment]) = selector.toList match {
case Nil => ""
- case Mirror.Segment.Label(head) :: rest =>
+ case Segment.Label(head) :: rest =>
val stringSegments = rest.map{
- case Mirror.Segment.Label(s) => "." + s
- case Mirror.Segment.Cross(vs) => "[" + vs.mkString(",") + "]"
+ case Segment.Label(s) => "." + s
+ case Segment.Cross(vs) => "[" + vs.mkString(",") + "]"
}
head + stringSegments.mkString
}
- sealed trait Segment
- object Segment{
- case class Label(value: String) extends Segment
- case class Cross(value: Seq[Any]) extends Segment
- }
+
def traverse[T, V, R](t: T, hierarchy: Mirror[T, V])
(f: (Mirror[T, _], => Seq[Segment]) => Seq[R]): Seq[R] = {
def rec[C](segmentsRev: List[Segment], h: Mirror[T, C]): Seq[R]= {
diff --git a/core/src/main/scala/mill/eval/Evaluator.scala b/core/src/main/scala/mill/eval/Evaluator.scala
index 17108307..ff2d64f2 100644
--- a/core/src/main/scala/mill/eval/Evaluator.scala
+++ b/core/src/main/scala/mill/eval/Evaluator.scala
@@ -6,7 +6,7 @@ import ammonite.ops._
import ammonite.runtime.SpecialClassLoader
import mill.define._
import mill.discover.{Discovered, Mirror}
-import mill.discover.Mirror.Segment
+import mill.define.Segment
import mill.util
import mill.util._
@@ -40,16 +40,15 @@ class Evaluator[T](val workspacePath: Path,
val transitive = Graph.transitiveTargets(goals)
val topoSorted = Graph.topoSorted(transitive)
val sortedGroups = Graph.groupAroundImportantTargets(topoSorted){
- case t: NamedTask[Any] if mapping.modulesToPaths.contains(t.owner) =>
- val segments = mapping.modulesToPaths(t.owner) :+ Segment.Label(t.name)
+ case t: NamedTask[Any] =>
+ val segments = t.ctx.segments.value
val (finalTaskOverrides, enclosing) = t match{
- case t: Target[_] => mapping.segmentsToTargets(segments).overrides -> t.enclosing
- case c: mill.define.Command[_] => mapping.segmentsToCommands(segments).overrides -> c.enclosing
+ case t: Target[_] => mapping.segmentsToTargets(segments).ctx.overrides -> t.ctx.enclosing
+ case c: mill.define.Command[_] => mapping.segmentsToCommands(segments).overrides -> c.ctx.enclosing
}
- val delta = finalTaskOverrides - t.overrides
val additional =
- if (delta == 0) Nil
- else Seq(Segment.Label("override" + delta), Segment.Label(enclosing))
+ if (finalTaskOverrides == t.ctx.overrides) Nil
+ else Seq(Segment.Label("overriden"), Segment.Label(enclosing))
Right(Labelled(t, segments ++ additional))
case t if goals.contains(t) => Left(t)
@@ -127,9 +126,9 @@ class Evaluator[T](val workspacePath: Path,
case _ =>
val Seq(first, rest @_*) = labelledTarget.segments
- val msgParts = Seq(first.asInstanceOf[Mirror.Segment.Label].value) ++ rest.map{
- case Mirror.Segment.Label(s) => "." + s
- case Mirror.Segment.Cross(s) => "[" + s.mkString(",") + "]"
+ val msgParts = Seq(first.asInstanceOf[Segment.Label].value) ++ rest.map{
+ case Segment.Label(s) => "." + s
+ case Segment.Cross(s) => "[" + s.mkString(",") + "]"
}
if (labelledTarget.target.flushDest) rm(paths.dest)
@@ -258,8 +257,8 @@ object Evaluator{
meta: Path,
log: Path)
def makeSegmentStrings(segments: Seq[Segment]) = segments.flatMap{
- case Mirror.Segment.Label(s) => Seq(s)
- case Mirror.Segment.Cross(values) => values.map(_.toString)
+ case Segment.Label(s) => Seq(s)
+ case Segment.Cross(values) => values.map(_.toString)
}
def resolveDestPaths(workspacePath: Path, segments: Seq[Segment]): Paths = {
val segmentStrings = makeSegmentStrings(segments)
diff --git a/core/src/main/scala/mill/main/ReplApplyHandler.scala b/core/src/main/scala/mill/main/ReplApplyHandler.scala
index 1e88ee53..77926d45 100644
--- a/core/src/main/scala/mill/main/ReplApplyHandler.scala
+++ b/core/src/main/scala/mill/main/ReplApplyHandler.scala
@@ -3,7 +3,7 @@ package mill.main
import mill.define.Applicative.ApplyHandler
import mill.define.{Cross, Target, Task}
-import mill.discover.Mirror.Segment
+import mill.define.Segment
import mill.discover.{Discovered, Mirror}
import mill.eval.Evaluator
import mill.util.OSet
@@ -51,7 +51,7 @@ class ReplApplyHandler(pprinter0: pprint.PPrinter, evaluator: Evaluator[_]) exte
case m: mill.Module if evaluator.mapping.modulesToMirrors.contains(m) =>
val mirror = evaluator.mapping.modulesToMirrors(m)
pprint.Tree.Lazy( ctx =>
- Iterator(m.millModuleEnclosing.value, ":", m.millModuleLine.value.toString) ++
+ Iterator(m.millModuleEnclosing, ":", m.millModuleLine.toString) ++
(if (mirror.children.isEmpty) Nil
else ctx.applyPrefixColor("\nChildren:").toString +: mirror.children.map("\n ." + _._1)) ++
(if (mirror.commands.isEmpty) Nil
@@ -79,7 +79,7 @@ class ReplApplyHandler(pprinter0: pprint.PPrinter, evaluator: Evaluator[_]) exte
}
}
pprint.Tree.Lazy(ctx =>
- Iterator(t.enclosing, ":", t.lineNum.toString, "\n", ctx.applyPrefixColor("Inputs:").toString) ++
+ Iterator(t.ctx.enclosing, ":", t.ctx.lineNum.toString, "\n", ctx.applyPrefixColor("Inputs:").toString) ++
t.inputs.iterator.flatMap(rec).map("\n " + Mirror.renderSelector(_))
)
diff --git a/core/src/main/scala/mill/main/Resolve.scala b/core/src/main/scala/mill/main/Resolve.scala
index 6196cdc6..b8968091 100644
--- a/core/src/main/scala/mill/main/Resolve.scala
+++ b/core/src/main/scala/mill/main/Resolve.scala
@@ -1,21 +1,21 @@
package mill.main
-import mill.define.Task
+import mill.define.{Segment, Task}
import mill.define.Task.TaskModule
-import mill.discover.{Mirror}
+import mill.discover.Mirror
import ammonite.main.Router
object Resolve {
- def resolve[T, V](remainingSelector: List[Mirror.Segment],
+ def resolve[T, V](remainingSelector: List[Segment],
hierarchy: Mirror[T, V],
obj: T,
rest: Seq[String],
remainingCrossSelectors: List[List[String]],
- revSelectorsSoFar: List[Mirror.Segment]): Either[String, Task[Any]] = {
+ revSelectorsSoFar: List[Segment]): Either[String, Task[Any]] = {
remainingSelector match{
- case Mirror.Segment.Cross(_) :: Nil => Left("Selector cannot start with a [cross] segment")
- case Mirror.Segment.Label(last) :: Nil =>
+ case Segment.Cross(_) :: Nil => Left("Selector cannot start with a [cross] segment")
+ case Segment.Label(last) :: Nil =>
def target =
hierarchy.targets
.find(_.label == last)
@@ -44,7 +44,7 @@ object Resolve {
command orElse target orElse runDefault.headOption.flatten match{
case None => Left("Cannot resolve task " + Mirror.renderSelector(
- (Mirror.Segment.Label(last) :: revSelectorsSoFar).reverse)
+ (Segment.Label(last) :: revSelectorsSoFar).reverse)
)
// Contents of `either` *must* be a `Task`, because we only select
// methods returning `Task` in the discovery process
@@ -55,7 +55,7 @@ object Resolve {
case head :: tail =>
val newRevSelectorsSoFar = head :: revSelectorsSoFar
head match{
- case Mirror.Segment.Label(singleLabel) =>
+ case Segment.Label(singleLabel) =>
hierarchy.children.collectFirst{
case (label, child) if label == singleLabel => child
} match{
@@ -63,7 +63,7 @@ object Resolve {
case None => Left("Cannot resolve module " + Mirror.renderSelector(newRevSelectorsSoFar.reverse))
}
- case Mirror.Segment.Cross(cross) =>
+ case Segment.Cross(cross) =>
val Some((crossGen, childMirror)) = hierarchy.crossChildren
val crossOptions = crossGen(hierarchy.node(obj, remainingCrossSelectors))
if (crossOptions.contains(cross)){
diff --git a/core/src/main/scala/mill/main/RunScript.scala b/core/src/main/scala/mill/main/RunScript.scala
index 7e578fb0..e27d4e1c 100644
--- a/core/src/main/scala/mill/main/RunScript.scala
+++ b/core/src/main/scala/mill/main/RunScript.scala
@@ -9,7 +9,7 @@ import ammonite.util.Util.CodeSource
import ammonite.util.{Name, Res, Util}
import mill.{PathRef, define}
import mill.define.Task
-import mill.discover.Mirror.Segment
+import mill.define.Segment
import mill.discover.{Discovered, Mirror}
import mill.eval.{Evaluator, PathRef, Result}
import mill.util.{Logger, OSet, PrintLogger}
@@ -122,7 +122,7 @@ object RunScript{
for {
sel <- parseArgs(selectorString)
crossSelectors = sel.map{
- case Mirror.Segment.Cross(x) => x.toList.map(_.toString)
+ case Segment.Cross(x) => x.toList.map(_.toString)
case _ => Nil
}
target <- mill.main.Resolve.resolve(
@@ -161,11 +161,13 @@ object RunScript{
val json = for(t <- Seq(target)) yield {
t match {
case t: mill.define.NamedTask[_] =>
- for (segments <- evaluator.mapping.modulesToPaths.get(t.owner)) yield {
- val jsonFile = Evaluator.resolveDestPaths(evaluator.workspacePath, segments :+ Segment.Label(t.name)).meta
- val metadata = upickle.json.read(jsonFile.toIO)
- metadata(1)
- }
+ val segments = t.ctx.segments.value
+ val jsonFile = Evaluator.resolveDestPaths(
+ evaluator.workspacePath, segments
+ ).meta
+ val metadata = upickle.json.read(jsonFile.toIO)
+ Some(metadata(1))
+
case _ => None
}
}
@@ -178,10 +180,10 @@ object RunScript{
def parseSelector(input: String) = {
import fastparse.all._
val segment = P( CharsWhileIn(('a' to 'z') ++ ('A' to 'Z') ++ ('0' to '9')).! ).map(
- Mirror.Segment.Label
+ Segment.Label
)
val crossSegment = P( "[" ~ CharsWhile(c => c != ',' && c != ']').!.rep(1, sep=",") ~ "]" ).map(
- Mirror.Segment.Cross
+ Segment.Cross
)
val query = P( segment ~ ("." ~ segment | crossSegment).rep ~ End ).map{
case (h, rest) => h :: rest.toList
@@ -191,7 +193,7 @@ object RunScript{
- def parseArgs(selectorString: String): Either[String, List[Mirror.Segment]] = {
+ def parseArgs(selectorString: String): Either[String, List[Segment]] = {
import fastparse.all.Parsed
if (selectorString.isEmpty) Left("Selector cannot be empty")
else parseSelector(selectorString) match {