summaryrefslogtreecommitdiff
path: root/src/library/scala/reflect/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/library/scala/reflect/api')
-rw-r--r--src/library/scala/reflect/api/Attachment.scala10
-rw-r--r--src/library/scala/reflect/api/StandardNames.scala1
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala5
-rw-r--r--src/library/scala/reflect/api/Trees.scala18
-rw-r--r--src/library/scala/reflect/api/TypeTags.scala7
-rwxr-xr-xsrc/library/scala/reflect/api/Types.scala4
6 files changed, 35 insertions, 10 deletions
diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala
index dfd362ebe0..9fa5ceb0fb 100644
--- a/src/library/scala/reflect/api/Attachment.scala
+++ b/src/library/scala/reflect/api/Attachment.scala
@@ -7,10 +7,18 @@ package api
* 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.
*/
+// [Eugene] with the introduction of `attach` and `payload[T]` users don't need to create custom attachments anymore
+// however, we cannot move attachments to scala.reflect.internal, because they are used in Trees, which are implemented completely in scala.reflect.api
trait Attachment {
/** Gets the underlying position */
def pos: Position
/** Creates a copy of this attachment with its position updated */
- def withPos(pos: Position): Attachment
+ def withPos(newPos: Position): Attachment
+
+ /** Gets the underlying payload */
+ def payload: Any
+
+ /** Creates a copy of this attachment with its payload updated */
+ def withPayload(newPayload: Any): Attachment
}
diff --git a/src/library/scala/reflect/api/StandardNames.scala b/src/library/scala/reflect/api/StandardNames.scala
index d2110ede75..d39d44dd86 100644
--- a/src/library/scala/reflect/api/StandardNames.scala
+++ b/src/library/scala/reflect/api/StandardNames.scala
@@ -44,6 +44,7 @@ trait StandardNames { self: Universe =>
val MIRROR_FREE_PREFIX: TermName
val MIRROR_FREE_THIS_SUFFIX: TermName
val MIRROR_FREE_VALUE_SUFFIX: TermName
+ val MIRROR_SYMDEF_PREFIX: TermName
val MIXIN_CONSTRUCTOR: TermName
val MODULE_INSTANCE_FIELD: TermName
val OUTER: TermName
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index a154e5f7a0..e47bc7216e 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -173,6 +173,11 @@ trait Symbols { self: Universe =>
*/
def isSkolem : Boolean
+ /** Does this symbol represent an existentially bound type?
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isExistential : Boolean
+
/** Does this symbol represent a free type captured by reification?
*/
// needed for ones who wish to inspect reified trees
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index 6ddb2ea673..5ef73cba0c 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -85,10 +85,18 @@ 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 }
- private[this] var rawatt: Attachment = NoPosition
- def attachment: Attachment = rawatt
- def attachment_=(att: Attachment): Unit = rawatt = att
- def setAttachment(att: Attachment): this.type = { rawatt = att; this }
+ 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 }
private[this] var rawtpe: Type = _
@@ -238,7 +246,7 @@ trait Trees { self: Universe =>
duplicateTree(this).asInstanceOf[this.type]
private[scala] def copyAttrs(tree: Tree): this.type = {
- attachment = tree.attachment
+ rawatt = tree.rawatt
tpe = tree.tpe
if (hasSymbol) symbol = tree.symbol
this
diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala
index 4ffabe1c36..59a7c87f44 100644
--- a/src/library/scala/reflect/api/TypeTags.scala
+++ b/src/library/scala/reflect/api/TypeTags.scala
@@ -61,9 +61,8 @@ trait TypeTags { self: Universe =>
// assert(tpe != null)
def sym = tpe.typeSymbol
-
- def isConcrete = !isNotConcrete
- def isNotConcrete = tpe exists (_.typeSymbol.isAbstractType)
+ def isConcrete = tpe.isConcrete
+ def notConcrete = !isConcrete
def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe)
override def toString = {
@@ -124,7 +123,7 @@ trait TypeTags { self: Universe =>
// it's unsafe to use assert here, because we might run into deadlocks with Predef
// also see comments in ClassTags.scala
//assert(isConcrete, tpe)
- if (isNotConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind))
+ if (notConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind))
override def productPrefix = "ConcreteTypeTag"
}
diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala
index 12aad453b1..5e1c1af2fe 100755
--- a/src/library/scala/reflect/api/Types.scala
+++ b/src/library/scala/reflect/api/Types.scala
@@ -57,6 +57,10 @@ trait Types { self: Universe =>
*/
def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no?
+ /** Does this type refer to abstract types or is an abstract type?
+ */
+ def isConcrete: Boolean
+
/**
* Expands type aliases and converts higher-kinded TypeRefs to PolyTypes.
* Functions on types are also implemented as PolyTypes.