From 7ed56d3fcdee9900361c7d583521930a0b5066a2 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 9 May 2013 17:13:22 -0400 Subject: [PATCH] Show defining locations when there are cycles between derived settings --- main/src/main/scala/sbt/Project.scala | 10 +--------- util/collection/src/main/scala/sbt/Settings.scala | 13 ++++++++++++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index c82854180..890260a71 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -269,15 +269,7 @@ object Project extends ProjectExtra } val definingScoped = definingScope match { case Some(sc) => ScopedKey(sc, key); case None => scoped } val comp = Def.compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal, display) - val definedAt = comp get definingScoped map { c => - val posDefined = c.settings.flatMap(_.positionString.toList) - if (posDefined.size > 0) { - val header = if (posDefined.size == c.settings.size) "Defined at:" else - "Some of the defining occurrences:" - header + (posDefined.distinct mkString ("\n\t", "\n\t", "\n")) - } else "" - } getOrElse "" - + val definedAt = comp get definingScoped map { c => Def.definedAtString(c.settings).capitalize } getOrElse "" val cMap = Def.flattenLocals(comp) val related = cMap.keys.filter(k => k.key == key && k.scope != scope) diff --git a/util/collection/src/main/scala/sbt/Settings.scala b/util/collection/src/main/scala/sbt/Settings.scala index 232272323..2d5ef2159 100644 --- a/util/collection/src/main/scala/sbt/Settings.scala +++ b/util/collection/src/main/scala/sbt/Settings.scala @@ -256,6 +256,16 @@ trait Init[Scope] } } + def definedAtString(settings: Seq[Setting[_]]): String = + { + val posDefined = settings.flatMap(_.positionString.toList) + if (posDefined.size > 0) { + val header = if (posDefined.size == settings.size) "defined at:" else + "some of the defining occurrences:" + header + (posDefined.distinct mkString ("\n\t", "\n\t", "\n")) + } else "" + } + private[this] def derive(init: Seq[Setting[_]])(implicit delegates: Scope => Seq[Scope]): Seq[Setting[_]] = { import collection.mutable @@ -266,7 +276,8 @@ trait Init[Scope] } final class Deriveds(val key: AttributeKey[_], val settings: mutable.ListBuffer[Derived]) { def dependencies = settings.flatMap(_.dependencies) - override def toString = "Derived settings for " + key.label + // This is mainly for use in the cyclic reference error message + override def toString = s"Derived settings for ${key.label}, ${definedAtString(settings.map(_.setting))}" } // separate `derived` settings from normal settings (`defs`)