summaryrefslogtreecommitdiff
path: root/src/library/scala/reflect/api/Trees.scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-04-15 22:27:42 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-04-17 21:34:39 +0200
commit40c1fe388be22c0ea9c68afcb08b41b69148026e (patch)
tree6849e9cbaae7dbf18f84ac07383cdbc525570ea4 /src/library/scala/reflect/api/Trees.scala
parentb37350b4126a1030d1060fd982d2ade6e2e5bd8e (diff)
downloadscala-40c1fe388be22c0ea9c68afcb08b41b69148026e.tar.gz
scala-40c1fe388be22c0ea9c68afcb08b41b69148026e.tar.bz2
scala-40c1fe388be22c0ea9c68afcb08b41b69148026e.zip
assorted stability fixes
Diffstat (limited to 'src/library/scala/reflect/api/Trees.scala')
-rw-r--r--src/library/scala/reflect/api/Trees.scala43
1 files changed, 32 insertions, 11 deletions
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index 7548a6bdc0..6e2e8261e7 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -85,18 +85,39 @@ trait Trees { self: Universe =>
def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) // the "withPos" part is crucial to robustness
def setPos(newpos: Position): this.type = { pos = newpos; this }
+ // [Eugene] can we make this more type-safe
private var rawatt: Attachment = NoPosition
- private case class NontrivialAttachment(pos: api.Position, payload: Any) extends Attachment {
- def withPos(newPos: api.Position) = copy(pos = newPos, payload = payload)
- def withPayload(newPayload: Any) = copy(pos = pos, payload = newPayload)
- }
- // todo. annotate T with ClassTag and make pattern matcher use it
- // todo. support multiple attachments, and remove the assignment. only leave attach/detach
-// def attachment[T]: T = rawatt.payload.asInstanceOf[T]
-// def attachmentOpt[T]: Option[T] = try { Some(rawatt.payload.asInstanceOf[T]) } catch { case _: Throwable => None }
- def attachment: Any = rawatt.payload
- def attachment_=(att: Any): Unit = rawatt = NontrivialAttachment(pos, att)
- def setAttachment(att: Any): this.type = { attachment = att; this }
+ def attach(att: Any): Unit =
+ rawatt match {
+ case NontrivialAttachment(pos, payload) =>
+ val index = payload.indexWhere(p => p.getClass == att.getClass)
+ if (index == -1) payload += att
+ else payload(index) = att
+ case _ =>
+ rawatt = NontrivialAttachment(pos, collection.mutable.ListBuffer[Any](att))
+ }
+ def withAttachment(att: Any): this.type = { attach(att); this }
+ def detach(att: Any): Unit =
+ detach(att.getClass)
+ def detach(clazz: java.lang.Class[_]): Unit =
+ rawatt match {
+ case NontrivialAttachment(pos, payload) =>
+ val index = payload.indexWhere(p => p.getClass == clazz)
+ if (index != -1) payload.remove(index)
+ case _ =>
+ // do nothing
+ }
+ def withoutAttachment(att: Any): this.type = { detach(att); this }
+ def attachment[T: ClassTag]: T = attachmentOpt[T] getOrElse { throw new Error("no attachment of type %s".format(classTag[T].erasure)) }
+ def attachmentOpt[T: ClassTag]: Option[T] =
+ rawatt match {
+ case NontrivialAttachment(pos, payload) =>
+ val index = payload.indexWhere(p => p.getClass == classTag[T].erasure)
+ if (index != -1) Some(payload(index).asInstanceOf[T])
+ else None
+ case _ =>
+ None
+ }
private[this] var rawtpe: Type = _