summaryrefslogtreecommitdiff
path: root/core/src/main
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-11-04 09:09:02 -0700
committerLi Haoyi <haoyi.sg@gmail.com>2017-11-04 09:09:02 -0700
commit3b10725ee3a1f84855a0654c5e386bc7465816d3 (patch)
treedeb6574654db3aab8c855a31c475c94233678a98 /core/src/main
parentc5f3cb7fdcc610bd167460b75b22863f61d6fb4b (diff)
downloadmill-3b10725ee3a1f84855a0654c5e386bc7465816d3.tar.gz
mill-3b10725ee3a1f84855a0654c5e386bc7465816d3.tar.bz2
mill-3b10725ee3a1f84855a0654c5e386bc7465816d3.zip
First experiment using `Cacher interface` combined with `Caller` implicits to turn `def foo = T{}` into pseudo-`lazy val`s, that we can override in subclasses using stackable traits
Diffstat (limited to 'core/src/main')
-rw-r--r--core/src/main/scala/forge/Discovered.scala6
-rw-r--r--core/src/main/scala/forge/Evaluator.scala1
-rw-r--r--core/src/main/scala/forge/Target.scala15
-rw-r--r--core/src/main/scala/forge/util/Caller.scala12
4 files changed, 32 insertions, 2 deletions
diff --git a/core/src/main/scala/forge/Discovered.scala b/core/src/main/scala/forge/Discovered.scala
index 03577b1f..e3aa31f9 100644
--- a/core/src/main/scala/forge/Discovered.scala
+++ b/core/src/main/scala/forge/Discovered.scala
@@ -29,7 +29,11 @@ object Discovered {
val tpe = c.weakTypeTag[T].tpe
def rec(segments: List[String], t: c.Type): Seq[Seq[String]] = for {
m <- t.members.toSeq
- if m.isTerm && (m.asTerm.isGetter || m.asTerm.isLazy) || m.isModule
+ if
+ (m.isTerm && (m.asTerm.isGetter || m.asTerm.isLazy)) ||
+ m.isModule ||
+ (m.isMethod && m.typeSignature.paramLists.isEmpty && m.typeSignature.resultType <:< c.weakTypeOf[Target[_]])
+
res <- {
val extendedSegments = m.name.toString :: segments
val self =
diff --git a/core/src/main/scala/forge/Evaluator.scala b/core/src/main/scala/forge/Evaluator.scala
index 50dc46d4..3ef605b7 100644
--- a/core/src/main/scala/forge/Evaluator.scala
+++ b/core/src/main/scala/forge/Evaluator.scala
@@ -105,6 +105,7 @@ class Evaluator(workspacePath: Path,
)
val args = new Args(targetInputValues, targetDestPath)
+
val res = target.evaluate(args)
for(targetLabel <- labeling.get(target)){
terminalResults(target) = targetLabel
diff --git a/core/src/main/scala/forge/Target.scala b/core/src/main/scala/forge/Target.scala
index c1790960..df9d9cc3 100644
--- a/core/src/main/scala/forge/Target.scala
+++ b/core/src/main/scala/forge/Target.scala
@@ -32,6 +32,14 @@ abstract class Target[T] extends Target.Ops[T]{
}
object Target{
+ trait Cacher{
+ val cacherLazyMap = mutable.Map.empty[(Any, sourcecode.Line, sourcecode.Enclosing), Target[_]]
+ def T[T](t: T): Target[T] = macro impl[T]
+ def T[T](t: => Target[T])
+ (implicit c: forge.util.Caller, l: sourcecode.Line, e: sourcecode.Enclosing): Target[T] = {
+ cacherLazyMap.getOrElseUpdate((c, l, e), t).asInstanceOf[Target[T]]
+ }
+ }
class Target0[T](t: T) extends Target[T]{
lazy val t0 = t
val inputs = Nil
@@ -68,7 +76,12 @@ object Target{
val bindings = symbols.map(c.internal.valDef(_))
- val embedded = q"new forge.Target.Target1(forge.zipMap(..$exprs){ (..$bindings) => $transformed })"
+ val newTargetTree = q"new forge.Target.Target1(forge.zipMap(..$exprs){ (..$bindings) => $transformed })"
+
+ val embedded =
+ if (!(c.prefix.tree.tpe <:< typeOf[Cacher])) newTargetTree
+ else q"${c.prefix}.T($newTargetTree)"
+
c.Expr[Target[T]](embedded)
}
diff --git a/core/src/main/scala/forge/util/Caller.scala b/core/src/main/scala/forge/util/Caller.scala
new file mode 100644
index 00000000..30dcb22a
--- /dev/null
+++ b/core/src/main/scala/forge/util/Caller.scala
@@ -0,0 +1,12 @@
+package forge.util
+
+import scala.reflect.macros.blackbox
+import language.experimental.macros
+case class Caller(value: Any)
+object Caller {
+ implicit def generate: Caller = macro impl
+ def impl(c: blackbox.Context): c.Tree = {
+ import c.universe._
+ q"new _root_.forge.util.Caller(this)"
+ }
+}