summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/forge/DefCtx.scala79
-rw-r--r--src/main/scala/forge/Evaluator.scala23
-rw-r--r--src/main/scala/forge/Target.scala41
3 files changed, 28 insertions, 115 deletions
diff --git a/src/main/scala/forge/DefCtx.scala b/src/main/scala/forge/DefCtx.scala
deleted file mode 100644
index 3439f755..00000000
--- a/src/main/scala/forge/DefCtx.scala
+++ /dev/null
@@ -1,79 +0,0 @@
-package forge
-
-
-import scala.annotation.compileTimeOnly
-import scala.language.experimental.macros
-import scala.reflect.macros.blackbox._
-
-
-final case class DefCtx(baseLabel: String, anonId: Option[Int]){
- def label = baseLabel + anonId.getOrElse("")
-}
-object DefCtx{
- @compileTimeOnly("A DefCtx can only be provided directly within a T{} macro")
- implicit def dummy: DefCtx with Int = ???
-}
-
-object T{
- def apply[T](expr: T): T = macro applyImpl[T]
-
- def applyImpl[T: c.WeakTypeTag](c: Context)(expr: c.Expr[T]): c.Expr[T] = {
- import c.universe._
- var count = 0
- object transformer extends c.universe.Transformer {
- override def transform(tree: c.Tree): c.Tree = {
- if (tree.toString.startsWith("forge.") && tree.toString.endsWith(".DefCtx.dummy")) {
- count += 1
- c.typecheck(q"forge.DefCtx(sourcecode.Enclosing(), Some($count))")
- }else tree match{
- case Apply(fun, args) =>
- val extendedParams = fun.tpe.paramLists.head.padTo(
- args.length,
- fun.tpe.paramLists.head.lastOption.getOrElse(null)
- )
- val newArgs =
- for((sym, tree) <- extendedParams.zip(args))
- yield {
- if (sym.asTerm.isByNameParam) tree
- else transform(tree)
- }
- treeCopy.Apply(tree, transform(fun), newArgs)
-
- case t: DefDef => t
- case t: ClassDef => t
- case t: Function => t
- case t: LabelDef => t
- case t => super.transform(t)
- }
-
- }
- }
-
-
- def transformTerminal(tree: c.Tree): c.Tree = tree match{
- case Block(stats, returnExpr) =>
- treeCopy.Block(
- tree,
- stats.map(transformer.transform(_)),
- transformTerminal(returnExpr)
- )
-
- case Apply(fun, args) =>
- var isTransformed = false
- val newArgs = for(x <- args) yield {
- if (x.toString.startsWith("forge.") && x.toString.endsWith(".DefCtx.dummy")) {
- isTransformed = true
- c.typecheck(q"forge.DefCtx(sourcecode.Enclosing(), None)")
- }else transformer.transform(x)
- }
-
- assert(isTransformed)
- treeCopy.Apply(tree, transformer.transform(fun), newArgs)
-
- case _ => ???
- }
-
- val transformed = transformTerminal(expr.tree)
- c.Expr[T](transformed)
- }
-} \ No newline at end of file
diff --git a/src/main/scala/forge/Evaluator.scala b/src/main/scala/forge/Evaluator.scala
index 32a3c9d0..4d9a435e 100644
--- a/src/main/scala/forge/Evaluator.scala
+++ b/src/main/scala/forge/Evaluator.scala
@@ -8,7 +8,7 @@ import sourcecode.Enclosing
import scala.collection.mutable
class Evaluator(workspacePath: jnio.Path,
- enclosingBase: DefCtx){
+ labeling: Map[Target[_], Seq[String]]){
/**
* Cache from the ID of the first terminal target in a group to the has of
@@ -20,12 +20,14 @@ class Evaluator(workspacePath: jnio.Path,
jnio.Files.createDirectories(workspacePath)
val sortedGroups = Evaluator.groupAroundNamedTargets(
- Evaluator.topoSortedTransitiveTargets(targets)
+ Evaluator.topoSortedTransitiveTargets(targets),
+ labeling
)
val evaluated = new MutableOSet[Target[_]]
val results = mutable.Map.empty[Target[_], Any]
for (group <- sortedGroups){
+ println("Evaluating group " + group)
val (newResults, newEvaluated) = evaluateGroup(group, results)
evaluated.appendAll(newEvaluated)
for((k, v) <- newResults) results.put(k, v)
@@ -46,19 +48,19 @@ class Evaluator(workspacePath: jnio.Path,
val terminals = group.filter(!internalInputSet(_))
val primeTerminal = terminals.items(0)
- val enclosingStr = primeTerminal.defCtx.label
+
+ val primeLabel = labeling(primeTerminal).mkString("/")
val targetDestPath = workspacePath.resolve(
- jnio.Paths.get(enclosingStr.stripSuffix(enclosingBase.label))
+ jnio.Paths.get(primeLabel)
)
val anyDirty = group.exists(_.dirty)
deleteRec(targetDestPath)
val inputsHash = inputResults.hashCode
- resultCache.get(primeTerminal.defCtx.label) match{
+ resultCache.get(primeLabel) match{
case Some((hash, terminalResults))
if hash == inputsHash && !anyDirty =>
for((terminal, res) <- terminals.items.zip(terminalResults)){
-
newResults(terminal) = primeTerminal.formatter.reads(Json.parse(res)).get
}
@@ -69,7 +71,7 @@ class Evaluator(workspacePath: jnio.Path,
val targetInputValues = target.inputs.toVector.map(x =>
newResults.getOrElse(x, results(x))
)
- if (target.defCtx.anonId.isDefined) {
+ if (!labeling.contains(target)) {
val res = target.evaluate(new Args(targetInputValues, targetDestPath))
newResults(target) = res
}else{
@@ -83,7 +85,7 @@ class Evaluator(workspacePath: jnio.Path,
newResults(target) = res
}
}
- resultCache(primeTerminal.defCtx.label) = (inputsHash, terminalResults)
+ resultCache(primeLabel) = (inputsHash, terminalResults)
}
@@ -105,7 +107,8 @@ class Evaluator(workspacePath: jnio.Path,
object Evaluator{
class TopoSorted private[Evaluator] (val values: OSet[Target[_]])
case class Results(values: Seq[Any], evaluated: OSet[Target[_]])
- def groupAroundNamedTargets(topoSortedTargets: TopoSorted): OSet[OSet[Target[_]]] = {
+ def groupAroundNamedTargets(topoSortedTargets: TopoSorted,
+ labeling: Map[Target[_], Seq[String]]): OSet[OSet[Target[_]]] = {
val grouping = new MultiBiMap[Int, Target[_]]()
var groupCount = 0
@@ -120,7 +123,7 @@ object Evaluator{
val targetGroup = grouping.lookupValue(target)
for(upstream <- target.inputs){
grouping.lookupValueOpt(upstream) match{
- case None if upstream.defCtx.anonId.nonEmpty =>
+ case None if !labeling.contains(upstream) =>
grouping.add(targetGroup, upstream)
case Some(upstreamGroup) if upstreamGroup == targetGroup =>
val upstreamTargets = grouping.removeAll(upstreamGroup)
diff --git a/src/main/scala/forge/Target.scala b/src/main/scala/forge/Target.scala
index 6f434030..8966a729 100644
--- a/src/main/scala/forge/Target.scala
+++ b/src/main/scala/forge/Target.scala
@@ -5,10 +5,6 @@ import java.nio.{file => jnio}
import play.api.libs.json.{Format, Json}
abstract class Target[T](implicit formatter: Format[T]) extends Target.Ops[T]{
/**
- * Where in the Scala codebase was this target defined?
- */
- val defCtx: DefCtx
- /**
* What other Targets does this Target depend on?
*/
val inputs: Seq[Target[_]]
@@ -33,22 +29,19 @@ object Target{
val str = formatter.writes(res)
(res, Json.stringify(str))
}
- val defCtx: DefCtx
- def map[V: Format](f: T => V)(implicit defCtx: DefCtx) = {
- new Target.Mapped(this, f, defCtx)
+ def map[V: Format](f: T => V) = {
+ new Target.Mapped(this, f)
}
- def zip[V: Format](other: Target[V])(implicit defCtx: DefCtx) = {
- new Target.Zipped(this, other, defCtx)
+ def zip[V: Format](other: Target[V]) = {
+ new Target.Zipped(this, other)
}
def ~[V: Format, R: Format](other: Target[V])
- (implicit s: Implicits.Sequencer[T, V, R], defCtx: DefCtx): Target[R] = {
+ (implicit s: Implicits.Sequencer[T, V, R]): Target[R] = {
this.zip(other).map(s.apply _ tupled)
}
-
- override def toString = defCtx.label.split('.').last
}
- def test(inputs: Target[Int]*)(implicit defCtx: DefCtx) = {
- new Test(inputs, defCtx, pure = inputs.nonEmpty)
+ def test(inputs: Target[Int]*) = {
+ new Test(inputs, pure = inputs.nonEmpty)
}
/**
@@ -57,7 +50,6 @@ object Target{
* test how changes propagate.
*/
class Test(val inputs: Seq[Target[Int]],
- val defCtx: DefCtx,
val pure: Boolean) extends Target[Int]{
var counter = 0
var lastCounter = counter
@@ -67,36 +59,33 @@ object Target{
}
override def dirty = lastCounter != counter
}
- def traverse[T: Format](source: Seq[Target[T]])(implicit defCtx: DefCtx) = {
- new Traverse[T](source, defCtx)
+ def traverse[T: Format](source: Seq[Target[T]]) = {
+ new Traverse[T](source)
}
- class Traverse[T: Format](val inputs: Seq[Target[T]], val defCtx: DefCtx) extends Target[Seq[T]]{
+ class Traverse[T: Format](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,
- val defCtx: DefCtx) extends Target[V]{
+ class Mapped[T, V: Format](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],
- source2: Target[V],
- val defCtx: DefCtx) extends Target[(T, V)]{
+ source2: Target[V]) extends Target[(T, V)]{
def evaluate(args: Args) = (args(0), args(0))
val inputs = List(source1, source1)
}
- def path(path: jnio.Path)(implicit defCtx: DefCtx) = new Path(path, defCtx)
- class Path(path: jnio.Path, val defCtx: DefCtx) extends Target[jnio.Path]{
+ def path(path: jnio.Path) = new Path(path)
+ class Path(path: jnio.Path) extends Target[jnio.Path]{
def evaluate(args: Args) = path
val inputs = Nil
}
class Subprocess(val inputs: Seq[Target[_]],
- command: Args => Seq[String],
- val defCtx: DefCtx) extends Target[Subprocess.Result] {
+ command: Args => Seq[String]) extends Target[Subprocess.Result] {
def evaluate(args: Args) = {
jnio.Files.createDirectories(args.dest)