diff --git a/main/Build.scala b/main/Build.scala index 26b8c62ee..f5273e2d5 100644 --- a/main/Build.scala +++ b/main/Build.scala @@ -166,9 +166,13 @@ object Index (value, ScopedKey(scope, key.asInstanceOf[AttributeKey[Task[_]]])) // unclear why this cast is needed even with a type test in the above filter pairs.toMap[Task[_], ScopedKey[Task[_]]] } - def stringToKeyMap(settings: Settings[Scope]): Map[String, AttributeKey[_]] = + def allKeys(settings: Seq[Setting[_]]): Set[ScopedKey[_]] = + settings.flatMap(s => s.key +: s.dependsOn).toSet + def attributeKeys(settings: Settings[Scope]): Set[AttributeKey[_]] = + settings.data.values.flatMap(_.keys).toSet[AttributeKey[_]] + def stringToKeyMap(settings: Set[AttributeKey[_]]): Map[String, AttributeKey[_]] = { - val multiMap = settings.data.values.flatMap(_.keys).toSet[AttributeKey[_]].groupBy(_.label) + val multiMap = settings.groupBy(_.label) val duplicates = multiMap collect { case (k, xs) if xs.size > 1 => (k, xs.map(_.manifest)) } collect { case (k, xs) if xs.size > 1 => (k, xs) } if(duplicates.isEmpty) multiMap.collect { case (k, v) if validID(k) => (k, v.head) } toMap; diff --git a/main/KeyIndex.scala b/main/KeyIndex.scala index 78955d9f3..a4a5794ee 100644 --- a/main/KeyIndex.scala +++ b/main/KeyIndex.scala @@ -11,7 +11,7 @@ package sbt object KeyIndex { def empty: ExtendableKeyIndex = new KeyIndex0(emptyBuildIndex) - def apply(known: Seq[ScopedKey[_]]): ExtendableKeyIndex = + def apply(known: Iterable[ScopedKey[_]]): ExtendableKeyIndex = (empty /: known) { _ add _ } def combine(indices: Seq[KeyIndex]): KeyIndex = new KeyIndex { def buildURIs = concat(_.buildURIs) diff --git a/main/Load.scala b/main/Load.scala index 753dda16d..db4cf6fa4 100644 --- a/main/Load.scala +++ b/main/Load.scala @@ -121,7 +121,7 @@ object Load val settings = finalTransforms(buildConfigurations(loaded, getRootProject(projects), rootEval, config.injectSettings)) val delegates = config.delegates(loaded) val data = Project.makeSettings(settings, delegates, config.scopeLocal) - val index = structureIndex(data) + val index = structureIndex(data, settings) val streams = mkStreams(projects, loaded.root, data) (rootEval, new BuildStructure(projects, loaded.root, settings, data, index, streams, delegates, config.scopeLocal)) } @@ -160,15 +160,20 @@ object Load def setDefinitionKey[T](tk: Task[T], key: ScopedKey[_]): Task[T] = if(isDummy(tk)) tk else Task(tk.info.set(Keys.taskDefinitionKey, key), tk.work) - def structureIndex(settings: Settings[Scope]): StructureIndex = - new StructureIndex(Index.stringToKeyMap(settings), Index.taskToKeyMap(settings), Index.triggers(settings), KeyIndex(settings.allKeys( (s,k) => ScopedKey(s,k)))) + def structureIndex(data: Settings[Scope], settings: Seq[Setting[_]]): StructureIndex = + { + val keys = Index.allKeys(settings) + val attributeKeys = Index.attributeKeys(data) ++ keys.map(_.key) + val scopedKeys = keys ++ data.allKeys( (s,k) => ScopedKey(s,k)) + new StructureIndex(Index.stringToKeyMap(attributeKeys), Index.taskToKeyMap(data), Index.triggers(data), KeyIndex(scopedKeys)) + } // Reevaluates settings after modifying them. Does not recompile or reload any build components. def reapply(newSettings: Seq[Setting[_]], structure: BuildStructure): BuildStructure = { val transformed = finalTransforms(newSettings) val newData = Project.makeSettings(transformed, structure.delegates, structure.scopeLocal) - val newIndex = structureIndex(newData) + val newIndex = structureIndex(newData, transformed) val newStreams = mkStreams(structure.units, structure.root, newData) new BuildStructure(units = structure.units, root = structure.root, settings = transformed, data = newData, index = newIndex, streams = newStreams, delegates = structure.delegates, scopeLocal = structure.scopeLocal) }