From ae5af2116f301ced14714101beecfb7babda8794 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Wed, 11 Dec 2013 15:24:46 +0000 Subject: [PATCH] Derived settings to replace their DerivedSetting, not go at the beginning --- .../src/main/scala/sbt/Settings.scala | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/util/collection/src/main/scala/sbt/Settings.scala b/util/collection/src/main/scala/sbt/Settings.scala index 9c551d829..557113d01 100644 --- a/util/collection/src/main/scala/sbt/Settings.scala +++ b/util/collection/src/main/scala/sbt/Settings.scala @@ -301,6 +301,7 @@ trait Init[Scope] val dependencies = setting.dependencies.map(_.key) def triggeredBy = dependencies.filter(setting.trigger) val inScopes = new mutable.HashSet[Scope] + val outputs = new mutable.ListBuffer[Setting[_]] } final class Deriveds(val key: AttributeKey[_], val settings: mutable.ListBuffer[Derived]) { def dependencies = settings.flatMap(_.dependencies) @@ -312,6 +313,7 @@ trait Init[Scope] val (derived, rawDefs) = Util.separate[Setting[_],Derived,Setting[_]](init) { case d: DerivedSetting[_] => Left(new Derived(d)); case s => Right(s) } val defs = addLocal(rawDefs)(scopeLocal) + // group derived settings by the key they define val derivsByDef = new mutable.HashMap[AttributeKey[_], Deriveds] for(s <- derived) { @@ -329,6 +331,10 @@ trait Init[Scope] for(s <- derived; d <- s.triggeredBy) derivedBy.getOrElseUpdate(d, new mutable.ListBuffer) += s + // Map a DerivedSetting[_] to the `Derived` struct wrapping it. Used to ultimately replace a DerivedSetting with + // the `Setting`s that were actually derived from it: `Derived.outputs` + val derivedToStruct: Map[DerivedSetting[_], Derived] = (derived map { s => s.setting -> s }).toMap + // set of defined scoped keys, used to ensure a derived setting is only added if all dependencies are present val defined = new mutable.HashSet[ScopedKey[_]] def addDefs(ss: Seq[Setting[_]]) { for(s <- ss) defined += s.key } @@ -357,7 +363,9 @@ trait Init[Scope] val local = d.dependencies.flatMap(dep => scopeLocal(ScopedKey(scope, dep))) if(allDepsDefined(d, scope, local.map(_.key.key).toSet)) { d.inScopes.add(scope) - local :+ d.setting.setScope(scope) + val out = local :+ d.setting.setScope(scope) + d.outputs ++= out + out } else Nil } @@ -366,21 +374,22 @@ trait Init[Scope] } val processed = new mutable.HashSet[ScopedKey[_]] - // valid derived settings to be added before normal settings - val out = new mutable.ListBuffer[Setting[_]] // derives settings, transitively so that a derived setting can trigger another def process(rem: List[Setting[_]]): Unit = rem match { case s :: ss => val sk = s.key val ds = if(processed.add(sk)) deriveFor(sk) else Nil - out ++= ds addDefs(ds) process(ds ::: ss) case Nil => } process(defs.toList) - out.toList ++ defs + + // Take all the original defs and DerivedSettings along with locals, replace each DerivedSetting with the actual + // settings that were derived. + val allDefs = addLocal(init)(scopeLocal) + allDefs flatMap { case d: DerivedSetting[_] => (derivedToStruct get d map (_.outputs)).toStream.flatten; case s => Stream(s) } } sealed trait Initialize[T]