mirror of https://github.com/sbt/sbt.git
98 lines
3.0 KiB
Scala
98 lines
3.0 KiB
Scala
/*
|
|
* sbt
|
|
* Copyright 2011 - 2018, Lightbend, Inc.
|
|
* Copyright 2008 - 2010, Mark Harrah
|
|
* Licensed under Apache License 2.0 (see LICENSE)
|
|
*/
|
|
|
|
package sbt.internal.util
|
|
|
|
import sbt.util.Show
|
|
|
|
/** Define our settings system */
|
|
// A basic scope indexed by an integer.
|
|
final case class Scope(nestIndex: Int, idAtIndex: Int = 0)
|
|
|
|
// Extend the Init trait.
|
|
// (It is done this way because the Scope type parameter is used everywhere in Init.
|
|
// Lots of type constructors would become binary, which as you may know requires lots of type lambdas
|
|
// when you want a type function with only one parameter.
|
|
// That would be a general pain.)
|
|
case class SettingsExample() extends Init[Scope] {
|
|
// Provides a way of showing a Scope+AttributeKey[_]
|
|
val showFullKey: Show[ScopedKey[_]] = Show[ScopedKey[_]]((key: ScopedKey[_]) => {
|
|
s"${key.scope.nestIndex}(${key.scope.idAtIndex})/${key.key.label}"
|
|
})
|
|
|
|
// A sample delegation function that delegates to a Scope with a lower index.
|
|
val delegates: Scope => Seq[Scope] = {
|
|
case s @ Scope(index, proj) =>
|
|
s +: (if (index <= 0) Nil
|
|
else {
|
|
(if (proj > 0) List(Scope(index)) else Nil) ++: delegates(Scope(index - 1))
|
|
})
|
|
}
|
|
|
|
// Not using this feature in this example.
|
|
val scopeLocal: ScopeLocal = _ => Nil
|
|
|
|
// These three functions + a scope (here, Scope) are sufficient for defining our settings system.
|
|
}
|
|
|
|
/** Usage Example **/
|
|
case class SettingsUsage(val settingsExample: SettingsExample) {
|
|
import settingsExample._
|
|
|
|
// Define some keys
|
|
val a = AttributeKey[Int]("a")
|
|
val b = AttributeKey[Int]("b")
|
|
|
|
// Scope these keys
|
|
val a3 = ScopedKey(Scope(3), a)
|
|
val a4 = ScopedKey(Scope(4), a)
|
|
val a5 = ScopedKey(Scope(5), a)
|
|
|
|
val b4 = ScopedKey(Scope(4), b)
|
|
|
|
// Define some settings
|
|
val mySettings: Seq[Setting[_]] = Seq(
|
|
setting(a3, value(3)),
|
|
setting(b4, map(a4)(_ * 3)),
|
|
update(a5)(_ + 1)
|
|
)
|
|
|
|
// "compiles" and applies the settings.
|
|
// This can be split into multiple steps to access intermediate results if desired.
|
|
// The 'inspect' command operates on the output of 'compile', for example.
|
|
val applied: Settings[Scope] =
|
|
makeWithCompiledMap(mySettings)(delegates, scopeLocal, showFullKey)._2
|
|
|
|
// Show results.
|
|
/* for(i <- 0 to 5; k <- Seq(a, b)) {
|
|
println( k.label + i + " = " + applied.get( Scope(i), k) )
|
|
}*/
|
|
|
|
/**
|
|
* Output:
|
|
* For the None results, we never defined the value and there was no value to delegate to.
|
|
* For a3, we explicitly defined it to be 3.
|
|
* a4 wasn't defined, so it delegates to a3 according to our delegates function.
|
|
* b4 gets the value for a4 (which delegates to a3, so it is 3) and multiplies by 3
|
|
* a5 is defined as the previous value of a5 + 1 and
|
|
* since no previous value of a5 was defined, it delegates to a4, resulting in 3+1=4.
|
|
* b5 isn't defined explicitly, so it delegates to b4 and is therefore equal to 9 as well
|
|
* a0 = None
|
|
* b0 = None
|
|
* a1 = None
|
|
* b1 = None
|
|
* a2 = None
|
|
* b2 = None
|
|
* a3 = Some(3)
|
|
* b3 = None
|
|
* a4 = Some(3)
|
|
* b4 = Some(9)
|
|
* a5 = Some(4)
|
|
* b5 = Some(9)
|
|
*/
|
|
}
|