Rename Global as scope component to Zero

Fixes #3178

While working on the Scopes and Scope Delegation document, I noticed that the term Global in sbt is used for two different meaning.

1. Universal fallback scope component `*`
2. An alias for GlobalScope

This disambiguates the two by renaming ScopeAxis instance to Zero.
Since this is mostly internal to sbt code, the impact to the user should be minimal.
This commit is contained in:
Eugene Yokota 2017-05-08 00:34:10 -04:00
parent 6cd3cd2323
commit 2082f37e2a
26 changed files with 176 additions and 130 deletions

View File

@ -14,9 +14,9 @@ private final class DelegateIndex0(refs: Map[ProjectRef, ProjectDelegates]) exte
refs.get(ref) match {
case Some(pd) =>
pd.confs.get(conf) match {
case Some(cs) => cs; case None => Select(conf) :: Global :: Nil
case Some(cs) => cs; case None => Select(conf) :: Zero :: Nil
}
case None => Select(conf) :: Global :: Nil
case None => Select(conf) :: Zero :: Nil
}
}
private final class ProjectDelegates(val ref: ProjectRef,

View File

@ -5,6 +5,8 @@ import Previous._
import sbt.internal.util.{ ~>, IMap, RMap }
import sbt.util.{ Input, Output, StampedFormat }
import sjsonnew.JsonFormat
import Scope.Global
import scala.util.control.NonFatal
/**
* Reads the previous value of tasks on-demand. The read values are cached so that they are only read once per task execution.
@ -84,11 +86,11 @@ object Previous {
private def read[T](input: Input, format: JsonFormat[T]): Option[T] =
try Some(input.read()(format))
catch { case e: Exception => None }
catch { case NonFatal(_) => None }
private def write[T](output: Output, format: JsonFormat[T], value: T): Unit =
try output.write(value)(format)
catch { case e: Exception => () }
catch { case NonFatal(_) => () }
/** Public as a macro implementation detail. Do not call directly. */
def runtime[T](skey: TaskKey[T])(implicit format: JsonFormat[T]): Initialize[Task[Option[T]]] = {

View File

@ -26,8 +26,9 @@ final case class Scope(project: ScopeAxis[Reference],
def in(task: AttributeKey[_]): Scope = copy(task = Select(task))
}
object Scope {
val ThisScope = Scope(This, This, This, This)
val GlobalScope = Scope(Global, Global, Global, Global)
val ThisScope: Scope = Scope(This, This, This, This)
val Global: Scope = Scope(Zero, Zero, Zero, Zero)
val GlobalScope: Scope = Global
def resolveScope(thisScope: Scope, current: URI, rootProject: URI => String): Scope => Scope =
resolveProject(current, rootProject) compose replaceThis(thisScope) compose subThisProject
@ -188,33 +189,34 @@ object Scope {
case pr: ProjectRef => pr; case br: BuildRef => ProjectRef(br.build, rootProject(br.build))
}
val cLin = scope.config match {
case Select(conf) => index.config(configProj, conf); case _ => withGlobalAxis(scope.config)
case Select(conf) => index.config(configProj, conf); case _ => withZeroAxis(scope.config)
}
val tLin = scope.task match {
case t @ Select(task) => linearize(t)(taskInherit); case _ => withGlobalAxis(scope.task)
case t @ Select(task) => linearize(t)(taskInherit); case _ => withZeroAxis(scope.task)
}
val eLin = withGlobalAxis(scope.extra)
val eLin = withZeroAxis(scope.extra)
for (c <- cLin; t <- tLin; e <- eLin) yield Scope(px, c, t, e)
}
scope.project match {
case Global | This => globalProjectDelegates(scope)
case Zero | This => globalProjectDelegates(scope)
case Select(proj) =>
val resolvedProj = resolve(proj)
val projAxes: Seq[ScopeAxis[ResolvedReference]] =
resolvedProj match {
case pr: ProjectRef => index.project(pr)
case br: BuildRef => Select(br) :: Global :: Nil
case br: BuildRef => Select(br) :: Zero :: Nil
}
projAxes flatMap nonProjectScopes(resolvedProj)
}
}
def withGlobalAxis[T](base: ScopeAxis[T]): Seq[ScopeAxis[T]] =
if (base.isSelect) base :: Global :: Nil else Global :: Nil
def withZeroAxis[T](base: ScopeAxis[T]): Seq[ScopeAxis[T]] =
if (base.isSelect) base :: Zero :: Nil
else Zero :: Nil
def withGlobalScope(base: Scope): Seq[Scope] =
if (base == GlobalScope) GlobalScope :: Nil else base :: GlobalScope :: Nil
def withRawBuilds(ps: Seq[ScopeAxis[ProjectRef]]): Seq[ScopeAxis[ResolvedReference]] =
ps ++ (ps flatMap rawBuild).distinct :+ Global
ps ++ (ps flatMap rawBuild).distinct :+ Zero
def rawBuild(ps: ScopeAxis[ProjectRef]): Seq[ScopeAxis[BuildRef]] = ps match {
case Select(ref) => Select(BuildRef(ref.build)) :: Nil; case _ => Nil
@ -246,22 +248,26 @@ object Scope {
init: T): (T, Seq[ScopeAxis[T]]) =
(init, linearize(Select(init))(direct(ref, _)))
def linearize[T](axis: ScopeAxis[T], appendGlobal: Boolean = true)(
def linearize[T](axis: ScopeAxis[T], appendZero: Boolean = true)(
inherit: T => Seq[T]): Seq[ScopeAxis[T]] =
axis match {
case Select(x) => topologicalSort[T](x, appendGlobal)(inherit)
case Global | This => if (appendGlobal) Global :: Nil else Nil
case Select(x) => topologicalSort[T](x, appendZero)(inherit)
case Zero | This => if (appendZero) Zero :: Nil else Nil
}
def topologicalSort[T](node: T, appendGlobal: Boolean)(
def topologicalSort[T](node: T, appendZero: Boolean)(
dependencies: T => Seq[T]): Seq[ScopeAxis[T]] = {
val o = Dag.topologicalSortUnchecked(node)(dependencies).map(Select.apply)
if (appendGlobal) o ::: Global :: Nil else o
if (appendZero) o ::: Zero :: Nil
else o
}
def globalProjectDelegates(scope: Scope): Seq[Scope] =
if (scope == GlobalScope)
GlobalScope :: Nil
else
for (c <- withGlobalAxis(scope.config); t <- withGlobalAxis(scope.task);
e <- withGlobalAxis(scope.extra)) yield Scope(Global, c, t, e)
for {
c <- withZeroAxis(scope.config)
t <- withZeroAxis(scope.task)
e <- withZeroAxis(scope.extra)
} yield Scope(Zero, c, t, e)
}

View File

@ -3,26 +3,41 @@ package sbt
import sbt.internal.util.Types.some
sealed trait ScopeAxis[+S] {
def foldStrict[T](f: S => T, ifGlobal: T, ifThis: T): T = fold(f, ifGlobal, ifThis)
def fold[T](f: S => T, ifGlobal: => T, ifThis: => T): T = this match {
def foldStrict[T](f: S => T, ifZero: T, ifThis: T): T = fold(f, ifZero, ifThis)
def fold[T](f: S => T, ifZero: => T, ifThis: => T): T = this match {
case This => ifThis
case Global => ifGlobal
case Zero => ifZero
case Select(s) => f(s)
}
def toOption: Option[S] = foldStrict(some.fn, None, None)
def map[T](f: S => T): ScopeAxis[T] = foldStrict(s => Select(f(s)), Global, This)
def map[T](f: S => T): ScopeAxis[T] = foldStrict(s => Select(f(s)), Zero, This)
def isSelect: Boolean = false
}
/**
* This is a scope component that represents not being
* scoped by the user, which later could be further scoped automatically
* by sbt.
*/
case object This extends ScopeAxis[Nothing]
case object Global extends ScopeAxis[Nothing]
/**
* Zero is a scope component that represents not scoping.
* It is a universal fallback component that is strictly weaker
* than any other values on a scope axis.
*/
case object Zero extends ScopeAxis[Nothing]
/**
* Select is a type constructor that is used to wrap type `S`
* to make a scope component, equivalent of Some in Option.
*/
final case class Select[S](s: S) extends ScopeAxis[S] {
override def isSelect = true
}
object ScopeAxis {
implicit def scopeAxisToScope(axis: ScopeAxis[Nothing]): Scope =
Scope(axis, axis, axis, axis)
def fromOption[T](o: Option[T]): ScopeAxis[T] = o match {
case Some(v) => Select(v)
case None => Global
case None => Zero
}
}

View File

@ -264,7 +264,7 @@ object Cross {
import extracted._
val newSettings = projects.flatMap { project =>
val scope = Scope(Select(project), Global, Global, Global)
val scope = Scope(Select(project), Zero, Zero, Zero)
instance match {
case Some((home, inst)) =>
@ -285,7 +285,7 @@ object Cross {
// Filter out any old scala version settings that were added, this is just for hygiene.
val filteredRawAppend = session.rawAppend.filter(_.key match {
case ScopedKey(Scope(Select(ref), Global, Global, Global), key)
case ScopedKey(Scope(Select(ref), Zero, Zero, Zero), key)
if filterKeys.contains(key) && projects.contains(ref) =>
false
case _ => true

View File

@ -106,7 +106,7 @@ object Defaults extends BuildCommon {
def configSrcSub(key: SettingKey[File]): Initialize[File] =
Def.setting {
(key in ThisScope.copy(config = Global)).value / nameForSrc(configuration.value.name)
(key in ThisScope.copy(config = Zero)).value / nameForSrc(configuration.value.name)
}
def nameForSrc(config: String) = if (config == Configurations.Compile.name) "main" else config
def prefix(config: String) = if (config == Configurations.Compile.name) "" else config + "-"
@ -620,8 +620,18 @@ object Defaults extends BuildCommon {
testOnly := inputTests(testOnly).evaluated,
testQuick := inputTests(testQuick).evaluated
)
lazy val TaskGlobal: Scope = ThisScope.copy(task = Global)
lazy val ConfigGlobal: Scope = ThisScope.copy(config = Global)
/**
* A scope whose task axis is set to Zero.
*/
lazy val TaskZero: Scope = ThisScope.copy(task = Zero)
lazy val TaskGlobal: Scope = TaskZero
/**
* A scope whose configuration axis is set to Zero.
*/
lazy val ConfigZero: Scope = ThisScope.copy(config = Zero)
lazy val ConfigGlobal: Scope = ConfigZero
def testTaskOptions(key: Scoped): Seq[Setting[_]] =
inTask(key)(
Seq(
@ -631,9 +641,9 @@ object Defaults extends BuildCommon {
test in resolvedScoped.value.scope,
logBuffered.value)) +:
new TestStatusReporter(succeededFile(streams.in(test).value.cacheDirectory)) +:
testListeners.in(TaskGlobal).value
testListeners.in(TaskZero).value
},
testOptions := Tests.Listeners(testListeners.value) +: (testOptions in TaskGlobal).value,
testOptions := Tests.Listeners(testListeners.value) +: (testOptions in TaskZero).value,
testExecution := testExecutionTask(key).value
)) ++ inScope(GlobalScope)(
Seq(
@ -994,7 +1004,7 @@ object Defaults extends BuildCommon {
mappingsTask: Initialize[Task[Seq[(File, String)]]]) =
inTask(key)(
Seq(
key in TaskGlobal := packageTask.value,
key in TaskZero := packageTask.value,
packageConfiguration := packageConfigurationTask.value,
mappings := mappingsTask.value,
packagedArtifact := (artifact.value -> key.value),
@ -1187,7 +1197,7 @@ object Defaults extends BuildCommon {
else Map.empty[File, URL]
},
fileInputOptions := Seq("-doc-root-content", "-diagrams-dot-path"),
key in TaskGlobal := {
key in TaskZero := {
val s = streams.value
val cs: Compilers = compilers.value
val srcs = sources.value
@ -2747,7 +2757,7 @@ trait BuildExtra extends BuildCommon with DefExtra {
val add = (s: State) => BasicCommands.addAlias(s, name, value)
val remove = (s: State) => BasicCommands.removeAlias(s, name)
def compose(setting: SettingKey[State => State], f: State => State) =
setting in Global ~= (_ compose f)
setting in GlobalScope ~= (_ compose f)
Seq(compose(onLoad, add), compose(onUnload, remove))
}

View File

@ -22,7 +22,7 @@ import Keys.{
transformState
}
import Project.richInitializeTask
import Scope.GlobalScope
import Scope.Global
import scala.Console.RED
import std.Transform.DummyTaskMap
import TaskName._
@ -238,9 +238,9 @@ object EvaluateTask {
key in extracted.currentRef get structure.data getOrElse default
def injectSettings: Seq[Setting[_]] = Seq(
(state in GlobalScope) ::= dummyState,
(streamsManager in GlobalScope) ::= Def.dummyStreamsManager,
(executionRoots in GlobalScope) ::= dummyRoots
(state in Global) ::= dummyState,
(streamsManager in Global) ::= Def.dummyStreamsManager,
(executionRoots in Global) ::= dummyRoots
)
def evalPluginDef(log: Logger)(pluginDef: BuildStructure, state: State): PluginData = {

View File

@ -20,7 +20,7 @@ final case class Extracted(structure: BuildStructure,
/**
* Gets the value assigned to `key` in the computed settings map.
* If the project axis is not explicitly specified, it is resolved to be the current project according to the extracted `session`.
* Other axes are resolved to be `Global` if they are not specified.
* Other axes are resolved to be `Zero` if they are not specified.
*/
def get[T](key: SettingKey[T]): T = getOrError(inCurrent(key.scope), key.key)
def get[T](key: TaskKey[T]): Task[T] = getOrError(inCurrent(key.scope), key.key)
@ -28,7 +28,7 @@ final case class Extracted(structure: BuildStructure,
/**
* Gets the value assigned to `key` in the computed settings map wrapped in Some. If it does not exist, None is returned.
* If the project axis is not explicitly specified, it is resolved to be the current project according to the extracted `session`.
* Other axes are resolved to be `Global` if they are not specified.
* Other axes are resolved to be `Zero` if they are not specified.
*/
def getOpt[T](key: SettingKey[T]): Option[T] = structure.data.get(inCurrent(key.scope), key.key)
def getOpt[T](key: TaskKey[T]): Option[Task[T]] =
@ -40,7 +40,7 @@ final case class Extracted(structure: BuildStructure,
/**
* Runs the task specified by `key` and returns the transformed State and the resulting value of the task.
* If the project axis is not defined for the key, it is resolved to be the current project.
* Other axes are resolved to `Global` if unspecified.
* Other axes are resolved to `Zero` if unspecified.
*
* This method requests execution of only the given task and does not aggregate execution. See `runAggregated` for that.
*/
@ -59,7 +59,7 @@ final case class Extracted(structure: BuildStructure,
* and the resulting value of the input task.
*
* If the project axis is not defined for the key, it is resolved to be the current project.
* Other axes are resolved to `Global` if unspecified.
* Other axes are resolved to `Zero` if unspecified.
*
* This method requests execution of only the given task and does not aggregate execution.
*/
@ -90,7 +90,7 @@ final case class Extracted(structure: BuildStructure,
* Runs the tasks selected by aggregating `key` and returns the transformed State.
* If the project axis is not defined for the key, it is resolved to be the current project.
* The project axis is what determines where aggregation starts, so ensure this is set to what you want.
* Other axes are resolved to `Global` if unspecified.
* Other axes are resolved to `Zero` if unspecified.
*/
def runAggregated[T](key: TaskKey[T], state: State): State = {
val rkey = resolve(key.scopedKey)

View File

@ -19,7 +19,7 @@ import Keys.{
serverPort,
watch
}
import Scope.{ GlobalScope, ThisScope }
import Scope.{ Global, ThisScope }
import Def.{ Flattened, Initialize, ScopedKey, Setting }
import sbt.internal.{
Load,
@ -544,7 +544,7 @@ object Project extends ProjectExtra {
def orIdentity[T](opt: Option[T => T]): T => T = opt getOrElse idFun
def getHook[T](key: SettingKey[T => T], data: Settings[Scope]): T => T =
orIdentity(key in GlobalScope get data)
orIdentity(key in Global get data)
def getHooks(data: Settings[Scope]): (State => State, State => State) =
(getHook(Keys.onLoad, data), getHook(Keys.onUnload, data))

View File

@ -24,8 +24,8 @@ object ScopeFilter {
* Generally, always specify the project axis.
*/
def apply(projects: ProjectFilter = inProjects(ThisProject),
configurations: ConfigurationFilter = globalAxis,
tasks: TaskFilter = globalAxis): ScopeFilter =
configurations: ConfigurationFilter = zeroAxis,
tasks: TaskFilter = zeroAxis): ScopeFilter =
new ScopeFilter {
private[sbt] def apply(data: Data): Scope => Boolean = {
val pf = projects(data)
@ -77,23 +77,32 @@ object ScopeFilter {
/** Selects the Scopes used in `<key>.all(<ScopeFilter>)`.*/
type ScopeFilter = Base[Scope]
/** Selects Scopes with a global task axis. */
def inGlobalTask: TaskFilter = globalAxis[AttributeKey[_]]
/** Selects Scopes with a Zero task axis. */
def inZeroTask: TaskFilter = zeroAxis[AttributeKey[_]]
/** Selects Scopes with a global project axis. */
def inGlobalProject: ProjectFilter = globalAxis[Reference]
@deprecated("Use inZeroTask", "1.0.0")
def inGlobalTask: TaskFilter = inZeroTask
/** Selects Scopes with a global configuration axis. */
def inGlobalConfiguration: ConfigurationFilter = globalAxis[ConfigKey]
/** Selects Scopes with a Zero project axis. */
def inZeroProject: ProjectFilter = zeroAxis[Reference]
/** Selects all scopes that apply to a single project. Global and build-level scopes are excluded. */
@deprecated("Use inZeroProject", "1.0.0")
def inGlobalProject: ProjectFilter = inZeroProject
/** Selects Scopes with a Zero configuration axis. */
def inZeroConfiguration: ConfigurationFilter = zeroAxis[ConfigKey]
@deprecated("Use inZeroConfiguration", "1.0.0")
def inGlobalConfiguration: ConfigurationFilter = inZeroConfiguration
/** Selects all scopes that apply to a single project. Zero and build-level scopes are excluded. */
def inAnyProject: ProjectFilter =
selectAxis(const { case p: ProjectRef => true; case _ => false })
/** Accepts all values for the task axis except Global. */
/** Accepts all values for the task axis except Zero. */
def inAnyTask: TaskFilter = selectAny[AttributeKey[_]]
/** Accepts all values for the configuration axis except Global. */
/** Accepts all values for the configuration axis except Zero. */
def inAnyConfiguration: ConfigurationFilter = selectAny[ConfigKey]
/**
@ -201,9 +210,9 @@ object ScopeFilter {
private[this] def inResolvedProjects(projects: Data => Seq[ProjectRef]): ProjectFilter =
selectAxis(data => projects(data).toSet)
private[this] def globalAxis[T]: AxisFilter[T] = new AxisFilter[T] {
private[this] def zeroAxis[T]: AxisFilter[T] = new AxisFilter[T] {
private[sbt] def apply(data: Data): ScopeAxis[T] => Boolean =
_ == Global
_ == Zero
}
private[this] def selectAny[T]: AxisFilter[T] = selectAxis(const(const(true)))
private[this] def selectAxis[T](f: Data => T => Boolean): AxisFilter[T] = new AxisFilter[T] {

View File

@ -18,7 +18,7 @@ import sbt.util.Show
final class ParsedKey(val key: ScopedKey[_], val mask: ScopeMask)
object Act {
val GlobalString = "*"
val ZeroString = "*"
// this does not take aggregation into account
def scopedKey(index: KeyIndex,
@ -86,11 +86,9 @@ object Act {
task: Option[AttributeKey[_]],
extra: ScopeAxis[AttributeMap],
key: AttributeKey[_]): ScopedKey[_] =
ScopedKey(Scope(toAxis(proj, Global),
toAxis(conf map ConfigKey.apply, Global),
toAxis(task, Global),
extra),
key)
ScopedKey(
Scope(toAxis(proj, Zero), toAxis(conf map ConfigKey.apply, Zero), toAxis(task, Zero), extra),
key)
def select(allKeys: Seq[Parser[ParsedKey]], data: Settings[Scope])(
implicit show: Show[ScopedKey[_]]): Parser[ParsedKey] =
@ -119,8 +117,8 @@ object Act {
}
}
def selectByTask(ss: Seq[ParsedKey]): Seq[ParsedKey] = {
val (selects, globals) = ss.partition(_.key.scope.task.isSelect)
if (globals.nonEmpty) globals else selects
val (selects, zeros) = ss.partition(_.key.scope.task.isSelect)
if (zeros.nonEmpty) zeros else selects
}
def noValidKeys = failure("No such key.")
@ -147,7 +145,7 @@ object Act {
def config(confs: Set[String]): Parser[ParsedAxis[String]] = {
val sep = ':' !!! "Expected ':' (if selecting a configuration)"
token((GlobalString ^^^ ParsedGlobal | value(examples(ID, confs, "configuration"))) <~ sep) ?? Omitted
token((ZeroString ^^^ ParsedZero | value(examples(ID, confs, "configuration"))) <~ sep) ?? Omitted
}
def configs(explicit: ParsedAxis[String],
@ -158,7 +156,7 @@ object Act {
case Omitted =>
None +: defaultConfigurations(proj, index, defaultConfigs).flatMap(
nonEmptyConfig(index, proj))
case ParsedGlobal => None :: Nil
case ParsedZero => None :: Nil
case pv: ParsedValue[x] => Some(pv.value) :: Nil
}
def defaultConfigurations(
@ -206,7 +204,7 @@ object Act {
knownValues: IMap[AttributeKey, Set]): Parser[ScopeAxis[AttributeMap]] = {
val extrasP = extrasParser(knownKeys, knownValues)
val extras = token('(', hide = _ == 1 && knownValues.isEmpty) ~> extrasP <~ token(')')
optionalAxis(extras, Global)
optionalAxis(extras, Zero)
}
def taskAxis(d: Option[String],
@ -219,11 +217,11 @@ object Act {
val valid = allKnown ++ normKeys
val suggested = normKeys.map(_._1).toSet
val keyP = filterStrings(examples(ID, suggested, "key"), valid.keySet, "key") map valid
(token(value(keyP) | GlobalString ^^^ ParsedGlobal) <~ token("::".id)) ?? Omitted
(token(value(keyP) | ZeroString ^^^ ParsedZero) <~ token("::".id)) ?? Omitted
}
def resolveTask(task: ParsedAxis[AttributeKey[_]]): Option[AttributeKey[_]] =
task match {
case ParsedGlobal | Omitted => None
case ParsedZero | Omitted => None
case t: ParsedValue[AttributeKey[_]] @unchecked => Some(t.value)
}
@ -259,9 +257,9 @@ object Act {
}
def projectRef(index: KeyIndex, currentBuild: URI): Parser[ParsedAxis[ResolvedReference]] = {
val global = token(GlobalString ~ '/') ^^^ ParsedGlobal
val zero = token(ZeroString ~ '/') ^^^ ParsedZero
val trailing = '/' !!! "Expected '/' (if selecting a project)"
global | value(resolvedReference(index, currentBuild, trailing))
zero | value(resolvedReference(index, currentBuild, trailing))
}
def resolvedReference(index: KeyIndex,
currentBuild: URI,
@ -287,7 +285,7 @@ object Act {
current: ProjectRef): Option[ResolvedReference] =
parsed match {
case Omitted => Some(current)
case ParsedGlobal => None
case ParsedZero => None
case pv: ParsedValue[rr] => Some(pv.value)
}
@ -374,7 +372,7 @@ object Act {
sealed trait ParsedAxis[+T] {
final def isExplicit = this != Omitted
}
final object ParsedGlobal extends ParsedAxis[Nothing]
final object ParsedZero extends ParsedAxis[Nothing]
final object Omitted extends ParsedAxis[Nothing]
final class ParsedValue[T](val value: T) extends ParsedAxis[T]
def value[T](t: Parser[T]): Parser[ParsedAxis[T]] = t map { v =>

View File

@ -225,7 +225,7 @@ object Aggregation {
mask: ScopeMask): Seq[ScopedKey[T]] =
projectAggregates(key.scope.project.toOption, extra, reverse = true) flatMap { ref =>
val toResolve = key.scope.copy(project = Select(ref))
val resolved = Resolve(extra, Global, key.key, mask)(toResolve)
val resolved = Resolve(extra, Zero, key.key, mask)(toResolve)
val skey = ScopedKey(resolved, key.key)
if (aggregationEnabled(skey, extra.data)) skey :: Nil else Nil
}
@ -235,7 +235,7 @@ object Aggregation {
mask: ScopeMask): Seq[ScopedKey[T]] =
projectAggregates(key.scope.project.toOption, extra, reverse = false) map { ref =>
val toResolve = key.scope.copy(project = Select(ref))
val resolved = Resolve(extra, Global, key.key, mask)(toResolve)
val resolved = Resolve(extra, Zero, key.key, mask)(toResolve)
ScopedKey(resolved, key.key)
}

View File

@ -271,7 +271,7 @@ object BuildStreams {
def pathComponent[T](axis: ScopeAxis[T], scoped: ScopedKey[_], label: String)(
show: T => String): String =
axis match {
case Global => GlobalPath
case Zero => GlobalPath
case This =>
sys.error("Unresolved This reference for " + label + " in " + displayFull(scoped))
case Select(t) => show(t)
@ -293,7 +293,7 @@ object BuildStreams {
scoped: ScopedKey[_],
data: Settings[Scope]): File =
scoped.scope.project match {
case Global => refTarget(GlobalScope, units(root).localBase, data) / GlobalPath
case Zero => refTarget(GlobalScope, units(root).localBase, data) / GlobalPath
case Select(br @ BuildRef(uri)) => refTarget(br, units(uri).localBase, data) / BuildUnitPath
case Select(pr @ ProjectRef(uri, id)) => refTarget(pr, units(uri).defined(id).base, data)
case Select(pr) =>

View File

@ -8,6 +8,7 @@ import DefaultParsers._
import Def.ScopedKey
import Types.idFun
import java.io.File
import Scope.Global
object Inspect {
sealed trait Mode

View File

@ -20,6 +20,7 @@ import java.io.File
import Configurations.Compile
import Def.Setting
import Keys._
import Scope.Global
import sbt.io.IO

View File

@ -349,7 +349,7 @@ private[sbt] object Load {
// map This to thisScope, Select(p) to mapRef(uri, rootProject, p)
transformSettings(projectScope(ref), uri, rootProject, settings)
}
val buildScope = Scope(Select(BuildRef(uri)), Global, Global, Global)
val buildScope = Scope(Select(BuildRef(uri)), Zero, Zero, Zero)
val buildBase = baseDirectory :== build.localBase
val buildSettings =
transformSettings(buildScope,
@ -371,7 +371,7 @@ private[sbt] object Load {
settings: Seq[Setting[_]]): Seq[Setting[_]] =
Project.transform(Scope.resolveScope(thisScope, uri, rootProject), settings)
def projectScope(project: Reference): Scope = Scope(Select(project), Global, Global, Global)
def projectScope(project: Reference): Scope = Scope(Select(project), Zero, Zero, Zero)
def lazyEval(unit: BuildUnit): () => Eval = {
lazy val eval = mkEval(unit)

View File

@ -155,7 +155,7 @@ object LogManager {
Some("Stack trace suppressed: run %s for the full output.".format(command(context.useColor)))
}
def unwrapStreamsKey(key: ScopedKey[_]): ScopedKey[_] = key.scope.task match {
case Select(task) => ScopedKey(key.scope.copy(task = Global), task)
case Select(task) => ScopedKey(key.scope.copy(task = Zero), task)
case _ => key // should never get here
}

View File

@ -20,13 +20,16 @@ object Resolve {
}
}
def resolveTask(mask: ScopeMask)(scope: Scope): Scope =
if (mask.task) scope else scope.copy(task = Global)
if (mask.task) scope
else scope.copy(task = Zero)
def resolveProject(current: ScopeAxis[Reference], mask: ScopeMask)(scope: Scope): Scope =
if (mask.project) scope else scope.copy(project = current)
if (mask.project) scope
else scope.copy(project = current)
def resolveExtra(mask: ScopeMask)(scope: Scope): Scope =
if (mask.extra) scope else scope.copy(extra = Global)
if (mask.extra) scope
else scope.copy(extra = Zero)
def resolveConfig[P](index: BuildUtil[P], key: AttributeKey[_], mask: ScopeMask)(
scope: Scope): Scope =
@ -37,7 +40,7 @@ object Resolve {
case Select(ref) =>
val r = index resolveRef ref
(Some(r), index.projectFor(r))
case Global | This =>
case Zero | This =>
(None, index.rootProject(index.root))
}
val task = scope.task.toOption
@ -45,8 +48,7 @@ object Resolve {
val definesKey = (c: ScopeAxis[ConfigKey]) =>
keyIndex.keys(resolvedRef, c.toOption.map(_.name), task) contains key.label
val projectConfigs = index.configurations(proj).map(ck => Select(ck))
val config
: ScopeAxis[ConfigKey] = (Global +: projectConfigs) find definesKey getOrElse Global
val config: ScopeAxis[ConfigKey] = (Zero +: projectConfigs) find definesKey getOrElse Zero
scope.copy(config = config)
}
}

View File

@ -12,6 +12,7 @@ import java.io.File
import Keys._
import EvaluateConfigurations.{ evaluateConfiguration => evaluate }
import Configurations.Compile
import Scope.Global
import sbt.io.{ Hash, IO }

View File

@ -7,7 +7,7 @@ import sbt.librarymanagement.Configuration
import Project._
import Def.{ ScopedKey, Setting }
import Scope.GlobalScope
import Scope.Global
import Types.{ const, idFun }
import complete._
import DefaultParsers._
@ -230,8 +230,8 @@ private[sbt] object SettingCompletions {
"configuration")
val taskParser =
axisParser[AttributeKey[_]](_.task, k => keyScalaID(k.label), _.description, "task")
val nonGlobal = (configParser ~ taskParser) map { case (c, t) => Scope(This, c, t, Global) }
val global = inParser ~> token((Space ~ GlobalID) ^^^ GlobalScope)
val nonGlobal = (configParser ~ taskParser) map { case (c, t) => Scope(This, c, t, Zero) }
val global = inParser ~> token((Space ~ GlobalID) ^^^ Global)
global | nonGlobal
}
@ -377,8 +377,8 @@ private[sbt] object SettingCompletions {
appendableClasses.exists(_ isAssignableFrom underlying)
}
/** The simple name of the global scope axis, which can be used to reference it in the default setting context. */
final val GlobalID = Global.getClass.getSimpleName.stripSuffix("$")
/** The simple name of the Global scope, which can be used to reference it in the default setting context. */
final val GlobalID = Scope.Global.getClass.getSimpleName.stripSuffix("$")
/** Character used to quote a Scala identifier that would otherwise be interpreted as a keyword.*/
final val Backtick = '`'

View File

@ -30,7 +30,7 @@ object SettingQuery {
def projectRef(index: KeyIndex,
currentBuild: URI): Parser[ParsedExplicitAxis[ResolvedReference]] = {
val global = token(Act.GlobalString ~ '/') ^^^ ParsedExplicitGlobal
val global = token(Act.ZeroString ~ '/') ^^^ ParsedExplicitGlobal
val trailing = '/' !!! "Expected '/' (if selecting a project)"
global | explicitValue(Act.resolvedReference(index, currentBuild, trailing))
}

View File

@ -3,7 +3,6 @@ package sbt
import Project._
import sbt.internal.util.Types.idFun
import sbt.internal.TestBuild._
import org.scalacheck._
import Prop._
import Gen._
@ -27,16 +26,16 @@ object Delegates extends Properties("delegates") {
}
}
property("An initially Global axis is Global in all delegates") = allAxes(alwaysGlobal)
property("An initially Zero axis is Zero in all delegates") = allAxes(alwaysZero)
property("Projects precede builds precede Global") = forAll { (keys: Keys) =>
property("Projects precede builds precede Zero") = forAll { (keys: Keys) =>
allDelegates(keys) { (scope, ds) =>
val projectAxes = ds.map(_.project)
val nonProject = projectAxes.dropWhile {
case Select(_: ProjectRef) => true; case _ => false
}
val global = nonProject.dropWhile { case Select(_: BuildRef) => true; case _ => false }
global forall { _ == Global }
global forall { _ == Zero }
}
}
property("Initial scope present with all combinations of Global axes") = allAxes(
@ -66,16 +65,16 @@ object Delegates extends Properties("delegates") {
("Delegates:\n\t" + delegates.map(scope => Scope.display(scope, "_")).mkString("\n\t")) |:
f(scope, delegates)
}: _*)
def alwaysGlobal(s: Scope, ds: Seq[Scope], axis: Scope => ScopeAxis[_]): Prop =
(axis(s) != Global) ||
def alwaysZero(s: Scope, ds: Seq[Scope], axis: Scope => ScopeAxis[_]): Prop =
(axis(s) != Zero) ||
all(ds map { d =>
(axis(d) == Global): Prop
(axis(d) == Zero): Prop
}: _*)
def globalCombinations(s: Scope, ds: Seq[Scope], axis: Scope => ScopeAxis[_]): Prop = {
val mods = List[Scope => Scope](_.copy(project = Global),
_.copy(config = Global),
_.copy(task = Global),
_.copy(extra = Global))
val mods = List[Scope => Scope](_.copy(project = Zero),
_.copy(config = Zero),
_.copy(task = Zero),
_.copy(extra = Zero))
val modAndIdent = mods.map(_ :: idFun[Scope] :: Nil)
def loop(cur: Scope, acc: List[Scope], rem: List[Seq[Scope => Scope]]): Seq[Scope] =

View File

@ -47,7 +47,7 @@ object ParseKey extends Properties("Key parser test") {
}
}
property("An unspecified task axis resolves to Global") = forAllNoShrink(structureDefinedKey) {
property("An unspecified task axis resolves to Zero") = forAllNoShrink(structureDefinedKey) {
(skm: StructureKeyMask) =>
import skm.{ structure, key }
val mask = skm.mask.copy(task = false)
@ -57,12 +57,12 @@ object ParseKey extends Properties("Key parser test") {
("Mask: " + mask) |:
parse(structure, string) {
case Left(err) => false
case Right(sk) => sk.scope.task == Global
case Right(sk) => sk.scope.task == Zero
}
}
property(
"An unspecified configuration axis resolves to the first configuration directly defining the key or else Global") =
"An unspecified configuration axis resolves to the first configuration directly defining the key or else Zero") =
forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) =>
import skm.{ structure, key }
val mask = ScopeMask(config = false)

View File

@ -72,27 +72,27 @@ abstract class TestBuild {
}
x
}
lazy val (taskAxes, globalTaskAxis, onlyTaskAxis, multiTaskAxis) = {
lazy val (taskAxes, zeroTaskAxis, onlyTaskAxis, multiTaskAxis) = {
import collection.mutable
import mutable.HashSet
// task axis of Scope is set to Global and the value of the second map is the original task axis
// task axis of Scope is set to Zero and the value of the second map is the original task axis
val taskAxesMappings =
for ((scope, keys) <- data.data.toIterable; key <- keys.keys)
yield
(ScopedKey(scope.copy(task = Global), key), scope.task): (ScopedKey[_],
ScopeAxis[AttributeKey[_]])
(ScopedKey(scope.copy(task = Zero), key), scope.task): (ScopedKey[_],
ScopeAxis[AttributeKey[_]])
val taskAxes = Relation.empty ++ taskAxesMappings
val global = new HashSet[ScopedKey[_]]
val zero = new HashSet[ScopedKey[_]]
val single = new HashSet[ScopedKey[_]]
val multi = new HashSet[ScopedKey[_]]
for ((skey, tasks) <- taskAxes.forwardMap) {
def makeKey(task: ScopeAxis[AttributeKey[_]]) =
ScopedKey(skey.scope.copy(task = task), skey.key)
val hasGlobal = tasks(Global)
val hasGlobal = tasks(Zero)
if (hasGlobal)
global += skey
zero += skey
else {
val keys = tasks map makeKey
keys.size match {
@ -102,7 +102,7 @@ abstract class TestBuild {
}
}
}
(taskAxes, global.toSet, single.toSet, multi.toSet)
(taskAxes, zero.toSet, single.toSet, multi.toSet)
}
}
final class Env(val builds: Seq[Build], val tasks: Seq[Taskk]) {
@ -138,10 +138,10 @@ abstract class TestBuild {
)
lazy val allFullScopes: Seq[Scope] =
for {
(ref, p) <- (Global, root.root) +: allProjects.map { case (ref, p) => (Select(ref), p) }
t <- Global +: tasks.map(t => Select(t.key))
c <- Global +: p.configurations.map(c => Select(ConfigKey(c.name)))
} yield Scope(project = ref, config = c, task = t, extra = Global)
(ref, p) <- (Zero, root.root) +: allProjects.map { case (ref, p) => (Select(ref), p) }
t <- Zero +: tasks.map(t => Select(t.key))
c <- Zero +: p.configurations.map(c => Select(ConfigKey(c.name)))
} yield Scope(project = ref, config = c, task = t, extra = Zero)
}
def getKey: Taskk => AttributeKey[_] = _.key
def toConfigKey: Config => ConfigKey = c => ConfigKey(c.name)
@ -186,10 +186,10 @@ abstract class TestBuild {
tAxis <- oneOrGlobal(env.tasks map getKey)
pAxis <- orGlobal(
frequency((1, BuildRef(build.uri)), (3, ProjectRef(build.uri, project.id))))
} yield Scope(pAxis, cAxis, tAxis, Global)
} yield Scope(pAxis, cAxis, tAxis, Zero)
def orGlobal[T](gen: Gen[T]): Gen[ScopeAxis[T]] =
frequency((1, gen map Select.apply), (1, Global))
frequency((1, gen map Select.apply), (1, Zero))
def oneOrGlobal[T](gen: Seq[T]): Gen[ScopeAxis[T]] = orGlobal(oneOf(gen))
def makeParser(structure: Structure): Parser[ScopedKey[_]] = {

View File

@ -34,6 +34,7 @@ package object sbt
if (m.isDefined) Some(m.get) else None
final val ThisScope = Scope.ThisScope
final val Global = Scope.Global
final val GlobalScope = Scope.GlobalScope
import sbt.{ Configurations => C }

View File

@ -1,11 +1,12 @@
lazy val taskX = taskKey[Set[Int]]("numbers")
lazy val filterX = ScopeFilter( inDependencies(ThisProject, transitive=false, includeRoot=false) )
lazy val filterA: ScopeFilter.ScopeFilter = ScopeFilter(
lazy val filterA: ScopeFilter.ScopeFilter = ScopeFilter(
inAggregates( LocalProject(e.id) ),
inConfigurations(Compile,Test) || inGlobalConfiguration,
inTasks(console) || inGlobalTask
inConfigurations(Compile,Test) || inZeroConfiguration,
inTasks(console) || inZeroTask
)
lazy val eGlobal = Set(192, 210)
lazy val cGlobal = Set(123, 57)
lazy val cCompile = Set(694)