From f55414355e8492f57d126a7dcfec4804dbcfd67b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 13 Apr 2011 19:06:36 -0400 Subject: [PATCH] improve error messages for cycles --- main/Project.scala | 9 ++++++--- util/collection/Dag.scala | 27 +++++++++++++++++++-------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/main/Project.scala b/main/Project.scala index 4483c3aeb..7dd8ba10e 100644 --- a/main/Project.scala +++ b/main/Project.scala @@ -176,9 +176,12 @@ object Project extends Init[Scope] with ProjectExtra ss.map(_ mapReferenced f) } def translateUninitialized[T](f: => T): T = - try { f } catch { case u: Project.Uninitialized => - val msg = "Uninitialized reference to " + display(u.key) + " from " + display(u.refKey) - throw new Uninitialized(u.key, u.refKey, msg) + try { f } catch { + case u: Project.Uninitialized => + val msg = "Uninitialized reference to " + display(u.key) + " from " + display(u.refKey) + throw new Uninitialized(u.key, u.refKey, msg) + case c: Dag.Cyclic => + throw new MessageOnlyException(c.getMessage) } def delegates(structure: Load.BuildStructure, scope: Scope, key: AttributeKey[_]): Seq[ScopedKey[_]] = 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) + } }