summaryrefslogtreecommitdiff
path: root/src/library/scala/reflect/base/Attachments.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/library/scala/reflect/base/Attachments.scala')
-rw-r--r--src/library/scala/reflect/base/Attachments.scala42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/library/scala/reflect/base/Attachments.scala b/src/library/scala/reflect/base/Attachments.scala
new file mode 100644
index 0000000000..43e870fc4f
--- /dev/null
+++ b/src/library/scala/reflect/base/Attachments.scala
@@ -0,0 +1,42 @@
+package scala.reflect
+package base
+
+/** Attachments is a generalisation of Position.
+ * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads.
+ *
+ * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree
+ * imposing an unnecessary memory tax because of something that will not be used in most cases.
+ */
+abstract class Attachments { self =>
+
+ type Pos >: Null
+
+ /** Gets the underlying position */
+ def pos: Pos
+
+ /** Creates a copy of this attachment with its position updated */
+ def withPos(newPos: Pos): Attachments { type Pos = self.Pos }
+
+ /** Gets the underlying payload */
+ def all: Set[Any] = Set.empty
+
+ def get[T: ClassTag]: Option[T] =
+ (all find (_.getClass == classTag[T].runtimeClass)).asInstanceOf[Option[T]]
+
+ /** Creates a copy of this attachment with its payload updated */
+ def add(attachment: Any): Attachments { type Pos = self.Pos } =
+ new NonemptyAttachments(this.pos, all + attachment)
+
+ def remove[T: ClassTag]: Attachments { type Pos = self.Pos } = {
+ val newAll = all filterNot (_.getClass == classTag[T].runtimeClass)
+ if (newAll.isEmpty) pos.asInstanceOf[Attachments { type Pos = self.Pos }]
+ else new NonemptyAttachments(this.pos, newAll)
+ }
+
+ private class NonemptyAttachments(override val pos: Pos, override val all: Set[Any]) extends Attachments {
+ type Pos = self.Pos
+ def withPos(newPos: Pos) = new NonemptyAttachments(newPos, all)
+ }
+}
+
+