mirror of https://github.com/sbt/sbt.git
API docs for Attributes.scala
This commit is contained in:
parent
78178f8716
commit
983d87106b
|
|
@ -9,14 +9,32 @@ import scala.reflect.Manifest
|
|||
// T must be invariant to work properly.
|
||||
// Because it is sealed and the only instances go through AttributeKey.apply,
|
||||
// a single AttributeKey instance cannot conform to AttributeKey[T] for different Ts
|
||||
|
||||
/** A key in an [[AttributeMap]] that constrains its associated value to be of type `T`.
|
||||
* The key is uniquely defined by its [[label]] and type `T`, represented at runtime by [[manifest]]. */
|
||||
sealed trait AttributeKey[T] {
|
||||
|
||||
/** The runtime evidence for `T` */
|
||||
def manifest: Manifest[T]
|
||||
|
||||
@deprecated("Should only be used for compatibility during the transition from hyphenated labels to camelCase labels.", "0.13.0")
|
||||
def rawLabel: String
|
||||
|
||||
/** The label is the identifier for the key and is camelCase by convention. */
|
||||
def label: String
|
||||
|
||||
/** An optional, brief description of the key. */
|
||||
def description: Option[String]
|
||||
|
||||
/** In environments that support delegation, looking up this key when it has no associated value will delegate to the values associated with these keys.
|
||||
* The delegation proceeds in order the keys are returned here.*/
|
||||
def extend: Seq[AttributeKey[_]]
|
||||
|
||||
/** Specifies whether this key is a local, anonymous key (`true`) or not (`false`).
|
||||
* This is typically only used for programmatic, intermediate keys that should not be referenced outside of a specific scope. */
|
||||
def isLocal: Boolean
|
||||
|
||||
/** Identifies the relative importance of a key among other keys.*/
|
||||
def rank: Int
|
||||
}
|
||||
private[sbt] abstract class SharedAttributeKey[T] extends AttributeKey[T] {
|
||||
|
|
@ -69,24 +87,58 @@ object AttributeKey
|
|||
private[sbt] final val LocalLabel = "$local"
|
||||
}
|
||||
|
||||
/** An immutable map where a key is the tuple `(String,T)` for a fixed type `T` and can only be associated with values of type `T`.
|
||||
* It is therefore possible for this map to contain mappings for keys with the same label but different types.
|
||||
* Excluding this possibility is the responsibility of the client if desired. */
|
||||
trait AttributeMap
|
||||
{
|
||||
/** Gets the value of type `T` associated with the key `k`.
|
||||
* If a key with the same label but different type is defined, this method will fail. */
|
||||
def apply[T](k: AttributeKey[T]): T
|
||||
|
||||
/** Gets the value of type `T` associated with the key `k` or `None` if no value is associated.
|
||||
* If a key with the same label but a different type is defined, this method will return `None`. */
|
||||
def get[T](k: AttributeKey[T]): Option[T]
|
||||
|
||||
/** Returns this map without the mapping for `k`.
|
||||
* This method will not remove a mapping for a key with the same label but a different type. */
|
||||
def remove[T](k: AttributeKey[T]): AttributeMap
|
||||
|
||||
/** Returns true if this map contains a mapping for `k`.
|
||||
* If a key with the same label but a different type is defined in this map, this method will return `false`. */
|
||||
def contains[T](k: AttributeKey[T]): Boolean
|
||||
|
||||
/** Adds the mapping `k -> value` to this map, replacing any existing mapping for `k`.
|
||||
* Any mappings for keys with the same label but different types are unaffected. */
|
||||
def put[T](k: AttributeKey[T], value: T): AttributeMap
|
||||
|
||||
/** All keys with defined mappings. There may be multiple keys with the same `label`, but different types. */
|
||||
def keys: Iterable[AttributeKey[_]]
|
||||
|
||||
/** Adds the mappings in `o` to this map, with mappings in `o` taking precedence over existing mappings.*/
|
||||
def ++(o: Iterable[AttributeEntry[_]]): AttributeMap
|
||||
|
||||
/** Combines the mappings in `o` with the mappings in this map, with mappings in `o` taking precedence over existing mappings.*/
|
||||
def ++(o: AttributeMap): AttributeMap
|
||||
|
||||
/** All mappings in this map. The [[AttributeEntry]] type preserves the typesafety of mappings, although the specific types are unknown.*/
|
||||
def entries: Iterable[AttributeEntry[_]]
|
||||
|
||||
/** `true` if there are no mappings in this map, `false` if there are. */
|
||||
def isEmpty: Boolean
|
||||
}
|
||||
object AttributeMap
|
||||
{
|
||||
/** An [[AttributeMap]] without any mappings. */
|
||||
val empty: AttributeMap = new BasicAttributeMap(Map.empty)
|
||||
|
||||
/** Constructs an [[AttributeMap]] containing the given `entries`. */
|
||||
def apply(entries: Iterable[AttributeEntry[_]]): AttributeMap = empty ++ entries
|
||||
|
||||
/** Constructs an [[AttributeMap]] containing the given `entries`.*/
|
||||
def apply(entries: AttributeEntry[_]*): AttributeMap = empty ++ entries
|
||||
|
||||
/** Presents an `AttributeMap` as a natural transformation. */
|
||||
implicit def toNatTrans(map: AttributeMap): AttributeKey ~> Id = new (AttributeKey ~> Id) {
|
||||
def apply[T](key: AttributeKey[T]): T = map(key)
|
||||
}
|
||||
|
|
@ -116,20 +168,32 @@ private class BasicAttributeMap(private val backing: Map[AttributeKey[_], Any])
|
|||
}
|
||||
|
||||
// type inference required less generality
|
||||
/** A map entry where `key` is constrained to only be associated with a fixed value of type `T`. */
|
||||
final case class AttributeEntry[T](key: AttributeKey[T], value: T)
|
||||
{
|
||||
override def toString = key.label + ": " + value
|
||||
}
|
||||
|
||||
/** Associates a `metadata` map with `data`. */
|
||||
final case class Attributed[D](data: D)(val metadata: AttributeMap)
|
||||
{
|
||||
/** Retrieves the associated value of `key` from the metadata. */
|
||||
def get[T](key: AttributeKey[T]): Option[T] = metadata.get(key)
|
||||
|
||||
/** Defines a mapping `key -> value` in the metadata. */
|
||||
def put[T](key: AttributeKey[T], value: T): Attributed[D] = Attributed(data)(metadata.put(key, value))
|
||||
|
||||
/** Transforms the data by applying `f`. */
|
||||
def map[T](f: D => T): Attributed[T] = Attributed(f(data))(metadata)
|
||||
}
|
||||
object Attributed
|
||||
{
|
||||
/** Extracts the underlying data from the sequence `in`. */
|
||||
def data[T](in: Seq[Attributed[T]]): Seq[T] = in.map(_.data)
|
||||
|
||||
/** Associates empty metadata maps with each entry of `in`.*/
|
||||
def blankSeq[T](in: Seq[T]): Seq[Attributed[T]] = in map blank
|
||||
|
||||
/** Associates an empty metadata map with `data`. */
|
||||
def blank[T](data: T): Attributed[T] = Attributed(data)(AttributeMap.empty)
|
||||
}
|
||||
Loading…
Reference in New Issue