blob: dc9602df3d5ed5057b3b0bf0445d9f0677ff4a28 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
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
}
}
|