diff options
author | Li Haoyi <haoyi.sg@gmail.com> | 2017-10-31 19:45:09 -0700 |
---|---|---|
committer | Li Haoyi <haoyi.sg@gmail.com> | 2017-10-31 19:45:09 -0700 |
commit | bfc9b9fc16ac1f865a80482ecdbc06b1b400fcaf (patch) | |
tree | de92cca87ef7d3f911af5933c9b7fe9fbe7bb26d /src/main | |
parent | 33ee29edc7dcf580099dfc7482737129ac2bddd0 (diff) | |
download | mill-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.scala | 21 | ||||
-rw-r--r-- | src/main/scala/forge/Evaluator.scala | 28 | ||||
-rw-r--r-- | src/main/scala/forge/Target.scala | 25 | ||||
-rw-r--r-- | src/main/scala/forge/scalaplugin/Compile.scala | 2 | ||||
-rw-r--r-- | src/main/scala/forge/util/Labelled.scala | 8 | ||||
-rw-r--r-- | src/main/scala/forge/util/OSet.scala | 10 |
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] = { |