summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-10-31 19:45:09 -0700
committerLi Haoyi <haoyi.sg@gmail.com>2017-10-31 19:45:09 -0700
commitbfc9b9fc16ac1f865a80482ecdbc06b1b400fcaf (patch)
treede92cca87ef7d3f911af5933c9b7fe9fbe7bb26d /src/main
parent33ee29edc7dcf580099dfc7482737129ac2bddd0 (diff)
downloadmill-bfc9b9fc16ac1f865a80482ecdbc06b1b400fcaf.tar.gz
mill-bfc9b9fc16ac1f865a80482ecdbc06b1b400fcaf.tar.bz2
mill-bfc9b9fc16ac1f865a80482ecdbc06b1b400fcaf.zip
Move formatter off of `Target[_]` and into `Discovered`
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/forge/Discovered.scala21
-rw-r--r--src/main/scala/forge/Evaluator.scala28
-rw-r--r--src/main/scala/forge/Target.scala25
-rw-r--r--src/main/scala/forge/scalaplugin/Compile.scala2
-rw-r--r--src/main/scala/forge/util/Labelled.scala8
-rw-r--r--src/main/scala/forge/util/OSet.scala10
6 files changed, 60 insertions, 34 deletions
diff --git a/src/main/scala/forge/Discovered.scala b/src/main/scala/forge/Discovered.scala
index 75e82c25..a1a9aa65 100644
--- a/src/main/scala/forge/Discovered.scala
+++ b/src/main/scala/forge/Discovered.scala
@@ -1,15 +1,25 @@
package forge
+import forge.util.Labelled
+import play.api.libs.json.Format
+
import language.experimental.macros
import reflect.macros.blackbox.Context
-class Discovered[T](val value: Seq[(Seq[String], T => Target[_])]){
- def apply(t: T) = value.map{case (a, b) => (a, b(t)) }
+class Discovered[T](val value: Seq[(Seq[String], Format[_], T => Target[_])]){
+ def apply(t: T) = value.map{case (a, f, b) => (a, f, b(t)) }
}
object Discovered {
- def mapping[T: Discovered](t: T): Map[Target[_], Seq[String]] = {
- implicitly[Discovered[T]].apply(t).map(_.swap).toMap
+ def makeTuple[T, V](path: Seq[String], func: T => Target[V])(implicit f: Format[V]) = {
+ (path, f, func)
+ }
+
+
+ def mapping[T: Discovered](t: T): Map[Target[_], Labelled[_]] = {
+ implicitly[Discovered[T]].apply(t)
+ .map(x => x._3 -> Labelled(x._3, x._2.asInstanceOf[Format[Any]], x._1))
+ .toMap
}
implicit def apply[T]: Discovered[T] = macro applyImpl[T]
@@ -38,7 +48,8 @@ object Discovered {
val ident = segments.foldLeft[Tree](base)((prefix, name) =>
q"$prefix.${TermName(name)}"
)
- q"($segments, ($base: $tpe) => $ident)"
+
+ q"forge.Discovered.makeTuple($segments, ($base: $tpe) => $ident)"
}
c.Expr[Discovered[T]](q"new _root_.forge.Discovered($result)")
diff --git a/src/main/scala/forge/Evaluator.scala b/src/main/scala/forge/Evaluator.scala
index af3e4106..50dc46d4 100644
--- a/src/main/scala/forge/Evaluator.scala
+++ b/src/main/scala/forge/Evaluator.scala
@@ -1,13 +1,13 @@
package forge
-import play.api.libs.json.{JsValue, Json}
+import play.api.libs.json.{Format, JsValue, Json}
import scala.collection.mutable
import ammonite.ops._
-import forge.util.{Args, MultiBiMap, OSet}
+import forge.util.{Args, Labelled, MultiBiMap, OSet}
class Evaluator(workspacePath: Path,
- labeling: Map[Target[_], Seq[String]]){
+ labeling: Map[Target[_], Labelled[_]]){
def evaluate(targets: OSet[Target[_]]): Evaluator.Results = {
mkdir(workspacePath)
@@ -47,7 +47,7 @@ class Evaluator(workspacePath: Path,
externalInputs.toIterator.map(results).toVector.hashCode +
group.toIterator.map(_.sideHash).toVector.hashCode()
- val primeLabel = labeling(terminals.items(0))
+ val primeLabel = labeling(terminals.items(0)).segments
val targetDestPath = workspacePath / primeLabel
@@ -63,7 +63,7 @@ class Evaluator(workspacePath: Path,
case Some(terminalResults) =>
val newResults = mutable.LinkedHashMap.empty[Target[_], Any]
for((terminal, res) <- terminals.items.zip(terminalResults)){
- newResults(terminal) = terminal.formatter.reads(res).get
+ newResults(terminal) = labeling(terminal).format.reads(res).get
}
(newResults, Nil)
@@ -103,16 +103,16 @@ class Evaluator(workspacePath: Path,
val targetInputValues = target.inputs.toVector.map(x =>
newResults.getOrElse(x, results(x))
)
- if (!labeling.contains(target)) {
- newResults(target) = target.evaluate(new Args(targetInputValues, targetDestPath))
- } else {
- val (res, serialized) = target.evaluateAndWrite(
- new Args(targetInputValues, targetDestPath)
- )
- terminalResults(target) = serialized
- newResults(target) = res
+ val args = new Args(targetInputValues, targetDestPath)
+ val res = target.evaluate(args)
+ for(targetLabel <- labeling.get(target)){
+ terminalResults(target) = targetLabel
+ .format
+ .asInstanceOf[Format[Any]]
+ .writes(res.asInstanceOf[Any])
}
+ newResults(target) = res
}
(newResults, newEvaluated, terminalResults)
@@ -125,7 +125,7 @@ object Evaluator{
class TopoSorted private[Evaluator] (val values: OSet[Target[_]])
case class Results(values: Seq[Any], evaluated: OSet[Target[_]])
def groupAroundNamedTargets(topoSortedTargets: TopoSorted,
- labeling: Map[Target[_], Seq[String]]): MultiBiMap[Int, Target[_]] = {
+ labeling: Map[Target[_], Labelled[_]]): MultiBiMap[Int, Target[_]] = {
val grouping = new MultiBiMap.Mutable[Int, Target[_]]()
diff --git a/src/main/scala/forge/Target.scala b/src/main/scala/forge/Target.scala
index f95a2dda..f8205bed 100644
--- a/src/main/scala/forge/Target.scala
+++ b/src/main/scala/forge/Target.scala
@@ -4,7 +4,7 @@ package forge
import ammonite.ops.{ls, mkdir}
import forge.util.{Args, PathRef}
import play.api.libs.json.{Format, JsValue, Json}
-abstract class Target[T](implicit formatter: Format[T]) extends Target.Ops[T]{
+abstract class Target[T] extends Target.Ops[T]{
/**
* What other Targets does this Target depend on?
*/
@@ -24,40 +24,35 @@ abstract class Target[T](implicit formatter: Format[T]) extends Target.Ops[T]{
}
object Target{
- class Target0[T: Format](t: T) extends Target[T]{
+ class Target0[T](t: T) extends Target[T]{
val inputs = Nil
def evaluate(args: Args) = t
}
- implicit def apply[T: Format](t: T): Target[T] = new Target0(t)
- abstract class Ops[T](implicit val formatter: Format[T]){ this: Target[T] =>
- def evaluateAndWrite(args: Args): (T, JsValue) = {
- val res = evaluate(args)
- val str = formatter.writes(res)
- (res, str)
- }
- def map[V: Format](f: T => V) = new Target.Mapped(this, f)
+ implicit def apply[T](t: T): Target[T] = new Target0(t)
+ abstract class Ops[T]{ this: Target[T] =>
+ def map[V](f: T => V) = new Target.Mapped(this, f)
def filter(f: T => Boolean) = this
def withFilter(f: T => Boolean) = this
- def zip[V: Format](other: Target[V]) = new Target.Zipped(this, other)
+ def zip[V](other: Target[V]) = new Target.Zipped(this, other)
}
- def traverse[T: Format](source: Seq[Target[T]]) = {
+ def traverse[T](source: Seq[Target[T]]) = {
new Traverse[T](source)
}
- class Traverse[T: Format](val inputs: Seq[Target[T]]) extends Target[Seq[T]]{
+ class Traverse[T](val inputs: Seq[Target[T]]) extends Target[Seq[T]]{
def evaluate(args: Args) = {
for (i <- 0 until args.length)
yield args(i).asInstanceOf[T]
}
}
- class Mapped[T, V: Format](source: Target[T], f: T => V) extends Target[V]{
+ class Mapped[T, V](source: Target[T], f: T => V) extends Target[V]{
def evaluate(args: Args) = f(args(0))
val inputs = List(source)
}
- class Zipped[T: Format, V: Format](source1: Target[T],
+ class Zipped[T, V](source1: Target[T],
source2: Target[V]) extends Target[(T, V)]{
def evaluate(args: Args) = (args(0), args(0))
val inputs = List(source1, source1)
diff --git a/src/main/scala/forge/scalaplugin/Compile.scala b/src/main/scala/forge/scalaplugin/Compile.scala
index c4220ddd..77ff3a5e 100644
--- a/src/main/scala/forge/scalaplugin/Compile.scala
+++ b/src/main/scala/forge/scalaplugin/Compile.scala
@@ -16,6 +16,8 @@ object Compile {
def apply(scalaVersion: Target[String],
dependencies: Target[OSet[Dependency]]) = {
+ for((s, d) <- scalaVersion.zip(dependencies))
+ yield underlying(s, d)
}
def underlying(scalaVersion: String,
diff --git a/src/main/scala/forge/util/Labelled.scala b/src/main/scala/forge/util/Labelled.scala
new file mode 100644
index 00000000..a79d2d93
--- /dev/null
+++ b/src/main/scala/forge/util/Labelled.scala
@@ -0,0 +1,8 @@
+package forge.util
+
+import forge.Target
+import play.api.libs.json.Format
+
+case class Labelled[T](target: Target[T],
+ format: Format[T],
+ segments: Seq[String])
diff --git a/src/main/scala/forge/util/OSet.scala b/src/main/scala/forge/util/OSet.scala
index 34e297bd..43743cdc 100644
--- a/src/main/scala/forge/util/OSet.scala
+++ b/src/main/scala/forge/util/OSet.scala
@@ -1,6 +1,8 @@
package forge.util
+import play.api.libs.json._
+
import scala.collection.mutable
/**
@@ -20,6 +22,14 @@ trait OSet[V] extends TraversableOnce[V]{
}
object OSet{
+ implicit def jsonFormat[T: Format]: Format[OSet[T]] = new Format[OSet[T]] {
+ def writes(o: OSet[T]) = JsArray(o.items.map(implicitly[Format[T]].writes))
+
+ def reads(json: JsValue) = json match{
+ case x: JsArray => implicitly[Format[Seq[T]]].reads(x).map(OSet.from)
+ case _ => JsError("OSet needs to be an Array")
+ }
+ }
def apply[V](items: V*) = from(items)
def from[V](items: TraversableOnce[V]): OSet[V] = {