Derived settings to replace their DerivedSetting, not go at the beginning

This commit is contained in:
Dan Sanduleac 2013-12-11 15:24:46 +00:00 committed by Dan Sanduleac
parent e06c4efe4f
commit ae5af2116f
1 changed files with 14 additions and 5 deletions

View File

@ -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]