blob: dc9602df3d5ed5057b3b0bf0445d9f0677ff4a28 (
plain) (
tree)
|
|
package dotty.tools.dotc.util
/** A class inheriting from Attachment.Container supports
* adding, removing and lookup of attachments. Attachments are typed key/value pairs.
*/
object Attachment {
class Key[+V]
val NullKey = new Key[Null]
abstract class AttachmentLink[+V] extends DotClass {
private[Attachment] def key: Key[V]
private[Attachment] def value: V
private[Attachment] var next: Link[_]
def getAttachment[V](key: Key[V]): Option[V] =
if (this.key eq key) Some(this.value.asInstanceOf[V])
else if (next == null) None
else next.getAttachment(key)
def pushAttachment[V](key: Key[V], value: V): Unit = {
assert(!getAttachment(key).isDefined)
next = new Link(key, value, next)
}
def putAttachment[V](key: Key[V], value: V): Option[V] = {
if (next == null) {
next = new Link(key, value, null)
None
}
else if (next.key eq key) {
val nx = next
next = new Link(key, value, nx.next)
Some(nx.value.asInstanceOf[V])
}
else next.putAttachment(key, value)
}
def removeAttachment[V](key: Key[V]): Option[V] = {
if (next == null)
None
else if (next.key eq key) {
val nx = next
next = nx.next
Some(nx.value.asInstanceOf[V])
}
else next.removeAttachment(key)
}
def allAttachments: List[Any] =
if (next == null) Nil else next.allAttachments
}
private[Attachment] class Link[+V](val key: Key[V], val value: V, var next: Link[_])
extends AttachmentLink[V] {
override def allAttachments: List[Any] = value :: super.allAttachments
}
class Container extends AttachmentLink[Null] {
private[Attachment] def key = NullKey
private[Attachment] def value: Null = unsupported("value")
private[Attachment] var next: Link[_] = null
}
}
|