diff --git a/util/collection/Dag.scala b/util/collection/Dag.scala index 9d6a295ea..29b43038a 100644 --- a/util/collection/Dag.scala +++ b/util/collection/Dag.scala @@ -22,20 +22,31 @@ object Dag val finished = asSet(new java.util.LinkedHashSet[T]) def visitAll(nodes: Iterable[T]) = nodes foreach visit - def visit(dag : T){ - if (!discovered(dag)) { - discovered(dag) = true; - visitAll(dependencies(dag)); - finished += dag; + def visit(node : T){ + if (!discovered(node)) { + discovered(node) = true; + try { visitAll(dependencies(node)); } catch { case c: Cyclic => throw node :: c } + finished += node; } - else if(!finished(dag)) - throw new Cyclic(dag) + else if(!finished(node)) + throw new Cyclic(node) } visitAll(nodes); finished.toList; } - final class Cyclic(val value: Any) extends Exception("Cyclic reference involving " + value) + final class Cyclic(val value: Any, val all: List[Any], val complete: Boolean) + extends Exception( "Cyclic reference involving " + (if(complete) all.mkString(", ") else value) ) + { + def this(value: Any) = this(value, value :: Nil, false) + def ::(a: Any): Cyclic = + if(complete) + this + else if(a == value) + new Cyclic(value, all, true) + else + new Cyclic(value, a :: all, false) + } }