diff options
author | Li Haoyi <haoyi.sg@gmail.com> | 2017-12-10 19:18:17 -0800 |
---|---|---|
committer | Li Haoyi <haoyi.sg@gmail.com> | 2017-12-10 19:18:52 -0800 |
commit | 4970ee7de1ebd25617e6985699ea16c0f66948de (patch) | |
tree | ba819bab139778d9ea1272d2a432670d977d8a09 /core/src | |
parent | a687f3908c84d5149fe8ef32bfb73872d65675d2 (diff) | |
download | mill-4970ee7de1ebd25617e6985699ea16c0f66948de.tar.gz mill-4970ee7de1ebd25617e6985699ea16c0f66948de.tar.bz2 mill-4970ee7de1ebd25617e6985699ea16c0f66948de.zip |
`Core.compile()` now works in the build REPL
Diffstat (limited to 'core/src')
-rw-r--r-- | core/src/main/scala/mill/Main.scala | 13 | ||||
-rw-r--r-- | core/src/main/scala/mill/define/Applicative.scala | 15 | ||||
-rw-r--r-- | core/src/main/scala/mill/define/Task.scala | 3 | ||||
-rw-r--r-- | core/src/main/scala/mill/main/ReplApplyHandler.scala | 20 | ||||
-rw-r--r-- | core/src/test/scala/mill/define/ApplicativeTests.scala | 4 |
5 files changed, 44 insertions, 11 deletions
diff --git a/core/src/main/scala/mill/Main.scala b/core/src/main/scala/mill/Main.scala index 711f251e..df9e0dc6 100644 --- a/core/src/main/scala/mill/Main.scala +++ b/core/src/main/scala/mill/Main.scala @@ -118,9 +118,13 @@ object Main { s"""import $$file.^.build |import mill._ | - |@main def run(args: String*) = mill.Main(args, build, interp.watch, true/*interp.colors()*/) + |val discovered = implicitly[mill.discover.Discovered[build.type]] | - |@main def idea() = mill.scalaplugin.GenIdea(build)""".stripMargin + |@main def run(args: String*) = mill.Main(args, build, interp.watch, true)(discovered) + | + |@main def idea() = mill.scalaplugin.GenIdea(build)(discovered) + | + |implicit val replApplyHandler = new mill.main.ReplApplyHandler(build)(discovered)""".stripMargin ) import ammonite.main.Cli @@ -147,8 +151,9 @@ object Main { val runner = new ammonite.MainRunner( cliConfig.copy( - predefFile = Some(pwd / "build.sc"), - welcomeBanner = Some("") + predefFile = Some(pwd / 'out / "run.sc"), + predefCode = "import build._", + welcomeBanner = None ), System.out, System.err, System.in, System.out, System.err diff --git a/core/src/main/scala/mill/define/Applicative.scala b/core/src/main/scala/mill/define/Applicative.scala index 6d8ae3e2..686220f7 100644 --- a/core/src/main/scala/mill/define/Applicative.scala +++ b/core/src/main/scala/mill/define/Applicative.scala @@ -14,9 +14,16 @@ import scala.reflect.macros.blackbox.Context * Applier.zipMap(applyable1, applyable2){ (a1, a2, ctx) => ... a1 ... a2 ... } */ object Applicative { - trait Applyable[+T]{ + trait ApplyHandler[M[+_]]{ + def apply[T](t: M[T]): T + } + object ApplyHandler{ @compileTimeOnly("Target#apply() can only be used with a T{...} block") - def apply(): T = ??? + implicit def defaultApplyHandler[M[+_]]: ApplyHandler[M] = ??? + } + trait Applyable[M[+_], +T]{ + def self: M[T] + def apply()(implicit handler: ApplyHandler[M]): T = handler(self) } class ImplicitStub extends StaticAnnotation type Id[+T] = T @@ -64,7 +71,7 @@ object Applicative { def rec(t: Tree): Iterator[c.Tree] = Iterator(t) ++ t.children.flatMap(rec(_)) val bound = collection.mutable.Buffer.empty[(c.Tree, ValDef)] - val targetApplySym = typeOf[Applyable[_]].member(TermName("apply")) + val targetApplySym = typeOf[Applyable[Nothing, _]].member(TermName("apply")) // Derived from @olafurpg's // https://gist.github.com/olafurpg/596d62f87bf3360a29488b725fbc7608 @@ -75,7 +82,7 @@ object Applicative { c.internal.setInfo(ctxSym, weakTypeOf[Ctx]) val transformed = c.internal.typingTransform(t) { - case (t @ q"$fun.apply()", api) if t.symbol == targetApplySym => + case (t @ q"$fun.apply()($handler)", api) if t.symbol == targetApplySym => val localDefs = rec(fun).filter(_.isDef).map(_.symbol).toSet val banned = rec(t).filter(x => defs(x.symbol) && !localDefs(x.symbol)) diff --git a/core/src/main/scala/mill/define/Task.scala b/core/src/main/scala/mill/define/Task.scala index 3c170bab..8c91997b 100644 --- a/core/src/main/scala/mill/define/Task.scala +++ b/core/src/main/scala/mill/define/Task.scala @@ -7,7 +7,7 @@ import mill.util.Ctx import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context -abstract class Task[+T] extends Task.Ops[T] with Applyable[T]{ +abstract class Task[+T] extends Task.Ops[T] with Applyable[Task, T]{ /** * What other Targets does this Target depend on? */ @@ -29,6 +29,7 @@ abstract class Task[+T] extends Task.Ops[T] with Applyable[T]{ def asTarget: Option[Target[T]] = None def asCommand: Option[Command[T]] = None def asPersistent: Option[Persistent[T]] = None + def self = this } trait Target[+T] extends Task[T]{ diff --git a/core/src/main/scala/mill/main/ReplApplyHandler.scala b/core/src/main/scala/mill/main/ReplApplyHandler.scala new file mode 100644 index 00000000..fe8c13b6 --- /dev/null +++ b/core/src/main/scala/mill/main/ReplApplyHandler.scala @@ -0,0 +1,20 @@ +package mill.main + +import ammonite.ops.pwd +import mill.Main.discoverMirror +import mill.define.Applicative.ApplyHandler +import mill.define.Task +import mill.discover.Discovered +import mill.eval.Evaluator +import mill.util.{OSet, PrintLogger} + +class ReplApplyHandler[T: Discovered](obj: T) extends ApplyHandler[Task] { + override def apply[V](t: Task[V]) = discoverMirror(obj) match{ + case Left(err) => + throw new Exception("Failed discovery consistency check: " + err) + case Right(mirror) => + val log = new PrintLogger(true) + val evaluator = new Evaluator(pwd / 'out, Discovered.mapping(obj)(mirror), log) + evaluator.evaluate(OSet(t)).values.head.asInstanceOf[V] + } +} diff --git a/core/src/test/scala/mill/define/ApplicativeTests.scala b/core/src/test/scala/mill/define/ApplicativeTests.scala index 29177a03..9991b9f0 100644 --- a/core/src/test/scala/mill/define/ApplicativeTests.scala +++ b/core/src/test/scala/mill/define/ApplicativeTests.scala @@ -9,11 +9,11 @@ import scala.language.experimental.macros object ApplicativeTests extends TestSuite { implicit def optionToOpt[T](o: Option[T]): Opt[T] = new Opt(o) - class Opt[T](val o: Option[T]) extends Applicative.Applyable[T] + class Opt[T](val self: Option[T]) extends Applicative.Applyable[Option, T] object Opt extends Applicative.Applyer[Opt, Option, Applicative.Id, String]{ val injectedCtx = "helloooo" - def underlying[A](v: Opt[A]) = v.o + def underlying[A](v: Opt[A]) = v.self def apply[T](t: T): Option[T] = macro Applicative.impl[Option, T, String] type O[+T] = Option[T] |