diff --git a/main/settings/src/main/scala/sbt/Def.scala b/main/settings/src/main/scala/sbt/Def.scala index 1d0a480a7..ddbe70c71 100644 --- a/main/settings/src/main/scala/sbt/Def.scala +++ b/main/settings/src/main/scala/sbt/Def.scala @@ -3,7 +3,7 @@ package sbt import Types.const import complete.Parser import java.io.File - import Scope.ThisScope + import Scope.{ThisScope,GlobalScope} import KeyRanks.{DTask, Invisible} /** A concrete settings system that uses `sbt.Scope` for the scope type. */ @@ -44,6 +44,11 @@ object Def extends Init[Scope] with TaskMacroExtra (if(s.key.scope != ThisScope) Some(s"Scope cannot be defined for ${definedSettingString(s)}") else None ) orElse s.dependencies.find(k => k.scope != ThisScope).map(k => s"Scope cannot be defined for dependency ${k.key.label} of ${definedSettingString(s)}") + override def intersect(s1: Scope, s2: Scope)(implicit delegates: Scope => Seq[Scope]): Option[Scope] = + if (s2 == GlobalScope || delegates(s1).contains(s2)) Some(s1) // s1 is more specific + else if (s1 == GlobalScope || delegates(s2).contains(s1)) Some(s2) // s2 is more specific + else None + private[this] def definedSettingString(s: Setting[_]): String = s"derived setting ${s.key.key.label}${positionString(s)}" private[this] def positionString(s: Setting[_]): String = diff --git a/util/collection/src/main/scala/sbt/Settings.scala b/util/collection/src/main/scala/sbt/Settings.scala index af56cb4f8..bc88520f1 100644 --- a/util/collection/src/main/scala/sbt/Settings.scala +++ b/util/collection/src/main/scala/sbt/Settings.scala @@ -3,7 +3,7 @@ */ package sbt - import Types._ +import Types._ sealed trait Settings[Scope] { @@ -291,6 +291,11 @@ trait Init[Scope] } else "" } + /** + * Intersects two scopes, returning the more specific one if they intersect, or None otherwise. + * Not implemented here because we want to optimise for Scope.GlobalScope which is inaccessible here. */ + private[sbt] def intersect(s1: Scope, s2: Scope)(implicit delegates: Scope => Seq[Scope]): Option[Scope] = ??? + private[this] def deriveAndLocal(init: Seq[Setting[_]])(implicit delegates: Scope => Seq[Scope], scopeLocal: ScopeLocal): Seq[Setting[_]] = { import collection.mutable @@ -361,10 +366,6 @@ trait Init[Scope] val scope = sk.scope def localAndDerived(d: Derived): Seq[Setting[_]] = { def definingScope = d.setting.key.scope - def intersect(s1: Scope, s2: Scope): Option[Scope] = - if (delegates(s1).contains(s2)) Some(s1) // s1 is more specific - else if (delegates(s2).contains(s1)) Some(s2) // s2 is more specific - else None val outputScope = intersect(scope, definingScope) outputScope collect { case s if !d.inScopes.contains(s) && d.setting.filter(s) => val local = d.dependencies.flatMap(dep => scopeLocal(ScopedKey(s, dep)))