summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-09-19 15:04:50 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-09-19 22:47:10 +0200
commit3fa900ca0ea244ac54df75dc2fd6d711739eface (patch)
treebd37a549da114d7030a7cbce14ecc527058dd1ad /src/reflect
parenteadf1d2080e0ce763e4c1920a26b80c8b8609ca0 (diff)
downloadscala-3fa900ca0ea244ac54df75dc2fd6d711739eface.tar.gz
scala-3fa900ca0ea244ac54df75dc2fd6d711739eface.tar.bz2
scala-3fa900ca0ea244ac54df75dc2fd6d711739eface.zip
SI-6363 removes scala.reflect.base
As the experience has shown, there's no need for a separate layer of reflection in scala-library.jar. Therefore I'm putting an end to it.
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/api/Annotations.scala105
-rw-r--r--src/reflect/scala/reflect/api/Attachments.scala50
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala75
-rw-r--r--src/reflect/scala/reflect/api/Constants.scala27
-rw-r--r--src/reflect/scala/reflect/api/Exprs.scala139
-rw-r--r--src/reflect/scala/reflect/api/FlagSets.scala11
-rw-r--r--src/reflect/scala/reflect/api/JavaUniverse.scala27
-rw-r--r--src/reflect/scala/reflect/api/MirrorOf.scala107
-rw-r--r--src/reflect/scala/reflect/api/Mirrors.scala18
-rw-r--r--src/reflect/scala/reflect/api/Names.scala65
-rw-r--r--src/reflect/scala/reflect/api/Positions.scala15
-rw-r--r--src/reflect/scala/reflect/api/Scopes.scala50
-rw-r--r--src/reflect/scala/reflect/api/StandardDefinitions.scala99
-rw-r--r--src/reflect/scala/reflect/api/StandardNames.scala26
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala290
-rw-r--r--src/reflect/scala/reflect/api/TagInterop.scala47
-rw-r--r--src/reflect/scala/reflect/api/TreeCreator.scala26
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala1418
-rw-r--r--src/reflect/scala/reflect/api/TypeCreator.scala26
-rw-r--r--src/reflect/scala/reflect/api/TypeTags.scala354
-rw-r--r--src/reflect/scala/reflect/api/Types.scala451
-rw-r--r--src/reflect/scala/reflect/api/Universe.scala75
-rw-r--r--src/reflect/scala/reflect/api/package.scala87
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala47
-rw-r--r--src/reflect/scala/reflect/internal/Scopes.scala2
-rw-r--r--src/reflect/scala/reflect/internal/StdAttachments.scala2
-rw-r--r--src/reflect/scala/reflect/internal/StdCreators.scala8
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala1
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala1
-rw-r--r--src/reflect/scala/reflect/internal/package.scala2
-rw-r--r--src/reflect/scala/reflect/internal/util/Position.scala2
-rw-r--r--src/reflect/scala/reflect/macros/Reifiers.scala7
-rw-r--r--src/reflect/scala/reflect/macros/Universe.scala2
-rw-r--r--src/reflect/scala/reflect/macros/package.scala2
37 files changed, 3441 insertions, 233 deletions
diff --git a/src/reflect/scala/reflect/api/Annotations.scala b/src/reflect/scala/reflect/api/Annotations.scala
index 43e95f9902..37882a9f3c 100644
--- a/src/reflect/scala/reflect/api/Annotations.scala
+++ b/src/reflect/scala/reflect/api/Annotations.scala
@@ -3,26 +3,121 @@ package api
import scala.collection.immutable.ListMap
-trait Annotations extends base.Annotations { self: Universe =>
+/**
+ * Defines the type hierarchy for annotations.
+ */
+trait Annotations { self: Universe =>
+
+ /** Typed information about an annotation. It can be attached to either a symbol or an annotated type.
+ *
+ * Annotations are either ''Scala annotations'', which conform to [[scala.annotation.StaticAnnotation]]
+ * or ''Java annotations'', which conform to [[scala.annotation.ClassfileAnnotation]].
+ * Trait `ClassfileAnnotation` is automatically added to every Java annotation by the scalac classfile parser.
+ */
+ type Annotation >: Null <: AnyRef with AnnotationApi
+
+ /** A tag that preserves the identity of the `Annotation` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AnnotationTag: ClassTag[Annotation]
+
+ /** The constructor/deconstructor for `Annotation` instances. */
+ val Annotation: AnnotationExtractor
+
+ /** An extractor class to create and pattern match with syntax `Annotation(atp, scalaArgs, javaArgs)`.
+ * Here, `atp` is the annotation type, `scalaArgs` the arguments, and `javaArgs` the annotation's key-value
+ * pairs.
+ *
+ * Annotations are pickled, i.e. written to scala symtab attribute in the classfile.
+ * Annotations are written to the classfile as Java annotations if `atp` conforms to `ClassfileAnnotation`.
+ *
+ * For Scala annotations, arguments are stored in `scalaArgs` and `javaArgs` is empty. Arguments in
+ * `scalaArgs` are represented as typed trees. Note that these trees are not transformed by any phases
+ * following the type-checker. For Java annotations, `scalaArgs` is empty and arguments are stored in
+ * `javaArgs`.
+ */
+ abstract class AnnotationExtractor {
+ def apply(tpe: Type, scalaArgs: List[Tree], javaArgs: ListMap[Name, JavaArgument]): Annotation
+ def unapply(ann: Annotation): Option[(Type, List[Tree], ListMap[Name, JavaArgument])]
+ }
- override type Annotation >: Null <: AnyRef with AnnotationApi
trait AnnotationApi {
def tpe: Type
def scalaArgs: List[Tree]
def javaArgs: ListMap[Name, JavaArgument]
}
- override type LiteralArgument >: Null <: JavaArgument with LiteralArgumentApi
+ /** A Java annotation argument */
+ type JavaArgument >: Null <: AnyRef
+ implicit val JavaArgumentTag: ClassTag[JavaArgument]
+
+ /** A literal argument to a Java annotation as `"Use X instead"` in `@Deprecated("Use X instead")`*/
+ type LiteralArgument >: Null <: AnyRef with JavaArgument with LiteralArgumentApi
+
+ /** A tag that preserves the identity of the `LiteralArgument` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val LiteralArgumentTag: ClassTag[LiteralArgument]
+
+ /** The constructor/deconstructor for `LiteralArgument` instances. */
+ val LiteralArgument: LiteralArgumentExtractor
+
+ /** An extractor class to create and pattern match with syntax `LiteralArgument(value)`
+ * where `value` is the constant argument.
+ */
+ abstract class LiteralArgumentExtractor {
+ def apply(value: Constant): LiteralArgument
+ def unapply(arg: LiteralArgument): Option[Constant]
+ }
+
trait LiteralArgumentApi {
def value: Constant
}
- override type ArrayArgument >: Null <: JavaArgument with ArrayArgumentApi
+ /** An array argument to a Java annotation as in `@Target(value={TYPE,FIELD,METHOD,PARAMETER})`
+ */
+ type ArrayArgument >: Null <: AnyRef with JavaArgument with ArrayArgumentApi
+
+ /** A tag that preserves the identity of the `ArrayArgument` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ArrayArgumentTag: ClassTag[ArrayArgument]
+
+ /** The constructor/deconstructor for `ArrayArgument` instances. */
+ val ArrayArgument: ArrayArgumentExtractor
+
+ /** An extractor class to create and pattern match with syntax `ArrayArgument(args)`
+ * where `args` is the argument array.
+ */
+ abstract class ArrayArgumentExtractor {
+ def apply(args: Array[JavaArgument]): ArrayArgument
+ def unapply(arg: ArrayArgument): Option[Array[JavaArgument]]
+ }
+
trait ArrayArgumentApi {
def args: Array[JavaArgument]
}
- override type NestedArgument >: Null <: JavaArgument with NestedArgumentApi
+ /** A nested annotation argument to a Java annotation as `@Nested` in `@Outer(@Nested)`.
+ */
+ type NestedArgument >: Null <: AnyRef with JavaArgument with NestedArgumentApi
+
+ /** A tag that preserves the identity of the `NestedArgument` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val NestedArgumentTag: ClassTag[NestedArgument]
+
+ /** The constructor/deconstructor for `NestedArgument` instances. */
+ val NestedArgument: NestedArgumentExtractor
+
+ /** An extractor class to create and pattern match with syntax `NestedArgument(annotation)`
+ * where `annotation` is the nested annotation.
+ */
+ abstract class NestedArgumentExtractor {
+ def apply(annotation: Annotation): NestedArgument
+ def unapply(arg: NestedArgument): Option[Annotation]
+ }
+
trait NestedArgumentApi {
def annotation: Annotation
}
diff --git a/src/reflect/scala/reflect/api/Attachments.scala b/src/reflect/scala/reflect/api/Attachments.scala
new file mode 100644
index 0000000000..edbb0131ca
--- /dev/null
+++ b/src/reflect/scala/reflect/api/Attachments.scala
@@ -0,0 +1,50 @@
+package scala.reflect
+package api
+
+/** Attachments is a generalization of Position. Typically it stores a Position of a tree, but this can be extended to
+ * encompass arbitrary payloads. Payloads are stored in type-indexed slots, which can be read with `get[T]` and written
+ * with `update[T]` and `remove[T]`.
+ *
+ * Attachments always carry positions because we don't want to introduce an additional field for attachments in `Tree`
+ * imposing an unnecessary memory tax because of something that will not be used in most cases.
+ */
+abstract class Attachments { self =>
+
+ /** The position type of this attachment */
+ type Pos >: Null
+
+ /** The underlying position */
+ def pos: Pos
+
+ /** Creates a copy of this attachment with the position replaced by `newPos` */
+ def withPos(newPos: Pos): Attachments { type Pos = self.Pos }
+
+ /** The underlying payload with the guarantee that no two elements have the same type. */
+ def all: Set[Any] = Set.empty
+
+ private def matchesTag[T: ClassTag](datum: Any) =
+ classTag[T].runtimeClass == datum.getClass
+
+ /** An underlying payload of the given class type `T`. */
+ def get[T: ClassTag]: Option[T] =
+ (all filter matchesTag[T]).headOption.asInstanceOf[Option[T]]
+
+ /** Creates a copy of this attachment with the payload slot of T added/updated with the provided value.
+ *
+ * Replaces an existing payload of the same type, if exists.
+ */
+ def update[T: ClassTag](attachment: T): Attachments { type Pos = self.Pos } =
+ new NonemptyAttachments(this.pos, remove[T].all + attachment)
+
+ /** Creates a copy of this attachment with the payload of the given class type `T` removed. */
+ def remove[T: ClassTag]: Attachments { type Pos = self.Pos } = {
+ val newAll = all filterNot matchesTag[T]
+ 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)
+ }
+}
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
new file mode 100644
index 0000000000..2bb0cc3c76
--- /dev/null
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -0,0 +1,75 @@
+package scala.reflect
+package api
+
+/**
+ * This is an internal implementation class.
+ */
+trait BuildUtils { self: Universe =>
+
+ val build: BuildApi
+
+ // this API abstracts away the functionality necessary for reification
+ // it's too gimmicky and unstructured to be exposed directly in the universe
+ // but we need it in a publicly available place for reification to work
+
+ abstract class BuildApi {
+ /** Selects type symbol with given simple name `name` from the defined members of `owner`.
+ */
+ def selectType(owner: Symbol, name: String): TypeSymbol
+
+ /** Selects term symbol with given name and type from the defined members of prefix type
+ */
+ def selectTerm(owner: Symbol, name: String): TermSymbol
+
+ /** Selects overloaded method symbol with given name and index
+ */
+ def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol
+
+ /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
+ * the current symbol as its owner.
+ */
+ def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: FlagSet, isClass: Boolean): Symbol
+
+ /** Create a fresh free term symbol.
+ * @param name the name of the free variable
+ * @param value the value of the free variable at runtime
+ * @param flags (optional) flags of the free variable
+ * @param origin debug information that tells where this symbol comes from
+ */
+ def newFreeTerm(name: String, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol
+
+ /** Create a fresh free type symbol.
+ * @param name the name of the free variable
+ * @param flags (optional) flags of the free variable
+ * @param origin debug information that tells where this symbol comes from
+ */
+ def newFreeType(name: String, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol
+
+ /** Set symbol's type signature to given type.
+ * @return the symbol itself
+ */
+ def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S
+
+ /** Set symbol's annotations to given annotations `annots`.
+ */
+ def setAnnotations[S <: Symbol](sym: S, annots: List[Annotation]): S
+
+ def flagsFromBits(bits: Long): FlagSet
+
+ def emptyValDef: ValDef
+
+ def This(sym: Symbol): Tree
+
+ def Select(qualifier: Tree, sym: Symbol): Select
+
+ def Ident(sym: Symbol): Ident
+
+ def TypeTree(tp: Type): TypeTree
+
+ def thisPrefix(sym: Symbol): Type
+
+ def setType[T <: Tree](tree: T, tpe: Type): T
+
+ def setSymbol[T <: Tree](tree: T, sym: Symbol): T
+ }
+}
diff --git a/src/reflect/scala/reflect/api/Constants.scala b/src/reflect/scala/reflect/api/Constants.scala
index 6657245003..f2d8ef2eb9 100644
--- a/src/reflect/scala/reflect/api/Constants.scala
+++ b/src/reflect/scala/reflect/api/Constants.scala
@@ -6,10 +6,33 @@
package scala.reflect
package api
-trait Constants extends base.Constants {
+/**
+ * Defines the type hierachy for compile-time constants.
+ *
+ * @see [[scala.reflect]] for a description on how the class hierarchy is encoded here.
+ */
+trait Constants {
self: Universe =>
- override type Constant >: Null <: AnyRef with ConstantApi
+ /** The type of compile-time constants.
+ */
+ type Constant >: Null <: AnyRef with ConstantApi
+
+ /** A tag that preserves the identity of the `Constant` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ConstantTag: ClassTag[Constant]
+
+ /** The constructor/deconstructor for `Constant` instances. */
+ val Constant: ConstantExtractor
+
+ /** An extractor class to create and pattern match with syntax `Constant(value)`
+ * where `value` is the Scala value of the constant.
+ */
+ abstract class ConstantExtractor {
+ def apply(value: Any): Constant
+ def unapply(arg: Constant): Option[Any]
+ }
abstract class ConstantApi {
val value: Any
diff --git a/src/reflect/scala/reflect/api/Exprs.scala b/src/reflect/scala/reflect/api/Exprs.scala
new file mode 100644
index 0000000000..65b0eb9301
--- /dev/null
+++ b/src/reflect/scala/reflect/api/Exprs.scala
@@ -0,0 +1,139 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2012 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala.reflect
+package api
+
+import scala.reflect.runtime.{universe => ru}
+
+trait Exprs { self: Universe =>
+
+ /** Expr wraps an expression tree and tags it with its type. */
+ trait Expr[+T] extends Equals with Serializable {
+ val mirror: Mirror
+ /**
+ * Migrates the expression into another mirror, jumping into a different universe if necessary.
+ *
+ * This means that all symbolic references to classes/objects/packages in the expression
+ * will be re-resolved within the new mirror (typically using that mirror's classloader).
+ */
+ def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T]
+
+ /**
+ * The Scala syntax tree representing the wrapped expression.
+ */
+ def tree: Tree
+
+ /**
+ * Representation of the type of the wrapped expression tree as found via type tags.
+ */
+ def staticType: Type
+ /**
+ * Representation of the type of the wrapped expression tree as found in the tree.
+ */
+ def actualType: Type
+
+ /**
+ * A dummy method to mark expression splicing in reification.
+ *
+ * It should only be used within a `reify` call, which eliminates the `splice` call and embeds
+ * the wrapped tree into the reified surrounding expression.
+ * If used alone `splice` throws an exception when called at runtime.
+ *
+ * If you want to use an Expr in reification of some Scala code, you need to splice it in.
+ * For an expr of type `Expr[T]`, where `T` has a method `foo`, the following code
+ * {{{
+ * reify{ expr.splice.foo }
+ * }}}
+ * uses splice to turn an expr of type Expr[T] into a value of type T in the context of `reify`.
+ *
+ * It is equivalent to
+ * {{{
+ * Select( expr.tree, newTermName("foo") )
+ * }}}
+ *
+ * The following example code however does not compile
+ * {{{
+ * reify{ expr.foo }
+ * }}}
+ * because expr of type Expr[T] itself does not have a method foo.
+ */
+ def splice: T
+ /**
+ * A dummy value to denote cross-stage path-dependent type dependencies.
+ *
+ * For example for the following macro definition:
+ * {{{
+ * class X { type T }
+ * object Macros { def foo(x: X): x.T = macro Impls.foo_impl }
+ * }}}
+ *
+ * The corresponding macro implementation should have the following signature (note how the return type denotes path-dependency on x):
+ * {{{
+ * object Impls { def foo_impl(c: Context)(x: c.Expr[X]): c.Expr[x.value.T] = ... }
+ * }}}
+ */
+ val value: T
+
+ /** case class accessories */
+ override def canEqual(x: Any) = x.isInstanceOf[Expr[_]]
+ override def equals(x: Any) = x.isInstanceOf[Expr[_]] && this.mirror == x.asInstanceOf[Expr[_]].mirror && this.tree == x.asInstanceOf[Expr[_]].tree
+ override def hashCode = mirror.hashCode * 31 + tree.hashCode
+ override def toString = "Expr["+staticType+"]("+tree+")"
+ }
+
+ /**
+ * Constructor/Extractor for Expr.
+ *
+ * Can be useful, when having a tree and wanting to splice it in reify call,
+ * in which case the tree first needs to be wrapped in an expr.
+ */
+ object Expr {
+ def apply[T: WeakTypeTag](mirror: MirrorOf[self.type], treec: TreeCreator): Expr[T] = new ExprImpl[T](mirror.asInstanceOf[Mirror], treec)
+ def unapply[T](expr: Expr[T]): Option[Tree] = Some(expr.tree)
+ }
+
+ private class ExprImpl[+T: WeakTypeTag](val mirror: Mirror, val treec: TreeCreator) extends Expr[T] {
+ def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ val tag1 = (implicitly[WeakTypeTag[T]] in otherMirror).asInstanceOf[otherMirror.universe.WeakTypeTag[T]]
+ otherMirror.universe.Expr[T](otherMirror1, treec)(tag1)
+ }
+
+ lazy val tree: Tree = treec(mirror)
+ lazy val staticType: Type = implicitly[WeakTypeTag[T]].tpe
+ def actualType: Type = tree.tpe
+
+ def splice: T = throw new UnsupportedOperationException("""
+ |the function you're calling has not been spliced by the compiler.
+ |this means there is a cross-stage evaluation involved, and it needs to be invoked explicitly.
+ |if you're sure this is not an oversight, add scala-compiler.jar to the classpath,
+ |import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.""".trim.stripMargin)
+ lazy val value: T = throw new UnsupportedOperationException("""
+ |the value you're calling is only meant to be used in cross-stage path-dependent types.
+ |if you want to splice the underlying expression, use `<your expr>.splice`.
+ |if you want to get a value of the underlying expression, add scala-compiler.jar to the classpath,
+ |import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.""".trim.stripMargin)
+
+ private def writeReplace(): AnyRef = new SerializedExpr(treec, implicitly[WeakTypeTag[T]].in(ru.rootMirror))
+ }
+}
+
+private[scala] class SerializedExpr(var treec: TreeCreator, var tag: ru.WeakTypeTag[_]) extends Serializable {
+ private def writeObject(out: java.io.ObjectOutputStream): Unit = {
+ out.writeObject(treec)
+ out.writeObject(tag)
+ }
+
+ private def readObject(in: java.io.ObjectInputStream): Unit = {
+ treec = in.readObject().asInstanceOf[TreeCreator]
+ tag = in.readObject().asInstanceOf[ru.WeakTypeTag[_]]
+ }
+
+ private def readResolve(): AnyRef = {
+ import ru._
+ Expr(rootMirror, treec)(tag)
+ }
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala
index fdd43f1883..599c4ca426 100644
--- a/src/reflect/scala/reflect/api/FlagSets.scala
+++ b/src/reflect/scala/reflect/api/FlagSets.scala
@@ -3,10 +3,16 @@ package api
import scala.language.implicitConversions
-trait FlagSets extends base.FlagSets { self: Universe =>
+trait FlagSets { self: Universe =>
+ /** An abstract type representing sets of flags (like private, final, etc.) that apply to definition trees and symbols */
type FlagSet
+ /** A tag that preserves the identity of the `FlagSet` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val FlagSetTag: ClassTag[FlagSet]
+
trait FlagOps extends Any {
def | (right: FlagSet): FlagSet
}
@@ -99,4 +105,7 @@ trait FlagSets extends base.FlagSets { self: Universe =>
/** Flag indicating that tree represents a variable or a member initialized to the default value */
val DEFAULTINIT: FlagSet
}
+
+ /** The empty set of flags */
+ val NoFlags: FlagSet
}
diff --git a/src/reflect/scala/reflect/api/JavaUniverse.scala b/src/reflect/scala/reflect/api/JavaUniverse.scala
index f2388433c4..ba38381561 100644
--- a/src/reflect/scala/reflect/api/JavaUniverse.scala
+++ b/src/reflect/scala/reflect/api/JavaUniverse.scala
@@ -1,7 +1,7 @@
package scala.reflect
package api
-trait JavaUniverse extends Universe with Mirrors with TagInterop { self =>
+trait JavaUniverse extends Universe with Mirrors { self =>
type RuntimeClass = java.lang.Class[_]
@@ -13,5 +13,28 @@ trait JavaUniverse extends Universe with Mirrors with TagInterop { self =>
}
def runtimeMirror(cl: ClassLoader): Mirror
-}
+ override def typeTagToManifest[T: ClassTag](mirror0: Any, tag: Universe # TypeTag[T]): Manifest[T] = {
+ // SI-6239: make this conversion more precise
+ val mirror = mirror0.asInstanceOf[Mirror]
+ val runtimeClass = mirror.runtimeClass(tag.in(mirror).tpe)
+ Manifest.classType(runtimeClass).asInstanceOf[Manifest[T]]
+ }
+
+ override def manifestToTypeTag[T](mirror0: Any, manifest: Manifest[T]): Universe # TypeTag[T] =
+ TypeTag(mirror0.asInstanceOf[Mirror], new TypeCreator {
+ def apply[U <: Universe with Singleton](mirror: MirrorOf[U]): U # Type = {
+ mirror.universe match {
+ case ju: JavaUniverse =>
+ val jm = mirror.asInstanceOf[ju.Mirror]
+ val sym = jm.classSymbol(manifest.erasure)
+ val tpe =
+ if (manifest.typeArguments.isEmpty) sym.toType
+ else ju.appliedType(sym.toTypeConstructor, manifest.typeArguments map (targ => ju.manifestToTypeTag(jm, targ)) map (_.in(jm).tpe))
+ tpe.asInstanceOf[U # Type]
+ case u =>
+ u.manifestToTypeTag(mirror.asInstanceOf[u.Mirror], manifest).in(mirror).tpe
+ }
+ }
+ })
+}
diff --git a/src/reflect/scala/reflect/api/MirrorOf.scala b/src/reflect/scala/reflect/api/MirrorOf.scala
new file mode 100644
index 0000000000..cd5641e692
--- /dev/null
+++ b/src/reflect/scala/reflect/api/MirrorOf.scala
@@ -0,0 +1,107 @@
+package scala.reflect
+package api
+
+/**
+ * The base interface for all mirrors.
+ *
+ * @tparam U the type of the universe this mirror belongs to.
+ *
+ * This is defined outside the reflection universe cake pattern implementation
+ * so that it can be referenced from outside. For example TypeCreator and TreeCreator
+ * reference MirrorOf and also need to be defined outside the cake as they are
+ * used by type tags, which can be migrated between different universes and consequently
+ * cannot be bound to a fixed one.
+ *
+ * @see [[Mirrors]]
+ */
+abstract class MirrorOf[U <: Universe with Singleton] {
+ /** The universe this mirror belongs to. */
+ val universe: U
+
+ /** The class symbol of the `_root_` package */
+ def RootClass: U#ClassSymbol
+
+ /** The module symbol of the `_root_` package */
+ def RootPackage: U#ModuleSymbol
+
+ /** The module class symbol of the default (unnamed) package */
+ def EmptyPackageClass: U#ClassSymbol
+
+ /** The module symbol of the default (unnamed) package */
+ def EmptyPackage: U#ModuleSymbol
+
+ /** The symbol corresponding to the globally accessible class with the
+ * given fully qualified name `fullName`.
+ *
+ * If the name points to a type alias, it's recursively dealiased and its target is returned.
+ * If you need a symbol that corresponds to the type alias itself, load it directly from the package class:
+ *
+ * scala> cm.staticClass("scala.List")
+ * res0: reflect.runtime.universe.ClassSymbol = class List
+ *
+ * scala> res0.fullName
+ * res1: String = scala.collection.immutable.List
+ *
+ * scala> cm.staticPackage("scala")
+ * res2: reflect.runtime.universe.ModuleSymbol = package scala
+ *
+ * scala> res2.moduleClass.typeSignature member newTypeName("List")
+ * res3: reflect.runtime.universe.Symbol = type List
+ *
+ * scala> res3.fullName
+ * res4: String = scala.List
+ *
+ * To be consistent with Scala name resolution rules, in case of ambiguity between
+ * a package and an object, the object is never been considered.
+ *
+ * For example for the following code:
+ *
+ * package foo {
+ * class B
+ * }
+ *
+ * object foo {
+ * class A
+ * class B
+ * }
+ *
+ * staticClass("foo.B") will resolve to the symbol corresponding to the class B declared in the package foo, and
+ * staticClass("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this
+ * fully qualified class name is written inside any package in a Scala program).
+ *
+ * In the example above, to load a symbol that corresponds to the class B declared in the object foo,
+ * use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass.
+ */
+ def staticClass(fullName: String): U#ClassSymbol
+
+ /** The symbol corresponding to the globally accessible object with the
+ * given fully qualified name `fullName`.
+ *
+ * To be consistent with Scala name resolution rules, in case of ambiguity between
+ * a package and an object, the object is never been considered.
+ *
+ * For example for the following code:
+ *
+ * package foo {
+ * object B
+ * }
+ *
+ * object foo {
+ * object A
+ * object B
+ * }
+ *
+ * staticModule("foo.B") will resolve to the symbol corresponding to the object B declared in the package foo, and
+ * staticModule("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this
+ * fully qualified class name is written inside any package in a Scala program).
+ *
+ * In the example above, to load a symbol that corresponds to the object B declared in the object foo,
+ * use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass.
+ */
+ def staticModule(fullName: String): U#ModuleSymbol
+
+ /** The symbol corresponding to a package with the
+ * given fully qualified name `fullName`.
+ */
+ def staticPackage(fullName: String): U#ModuleSymbol
+}
diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala
index 8c4c423221..c935533027 100644
--- a/src/reflect/scala/reflect/api/Mirrors.scala
+++ b/src/reflect/scala/reflect/api/Mirrors.scala
@@ -1,7 +1,23 @@
package scala.reflect
package api
-trait Mirrors extends base.Mirrors { self: Universe =>
+/**
+ * Defines a type hierarchy for mirrors.
+ *
+ * Every universe has one or more mirrors. A mirror defines a hierarchy of symbols starting with the root package `_root_`
+ * and provides methods to locate and define classes and singleton objects in that hierarchy.
+ *
+ * On the JVM, there is a one to one correspondance between class loaders and mirrors.
+ */
+trait Mirrors { self: Universe =>
+
+ /** The base type of all mirrors of this universe */
+ type Mirror >: Null <: MirrorOf[self.type]
+
+ /** The root mirror of this universe. This mirror contains standard Scala classes and types such as `Any`, `AnyRef`, `AnyVal`,
+ * `Nothing`, `Null`, and all classes loaded from scala-library, which are shared across all mirrors within the enclosing universe.
+ */
+ val rootMirror: Mirror
type RuntimeClass >: Null
diff --git a/src/reflect/scala/reflect/api/Names.scala b/src/reflect/scala/reflect/api/Names.scala
index d6868c26ab..e8665ca736 100644
--- a/src/reflect/scala/reflect/api/Names.scala
+++ b/src/reflect/scala/reflect/api/Names.scala
@@ -2,23 +2,52 @@ package scala.reflect
package api
/** A trait that manages names.
- * A name is a string in one of two name universes: terms and types.
- * The same string can be a name in both universes.
- * Two names are equal if they represent the same string and they are
- * members of the same universe.
*
- * Names are interned. That is, for two names `name11 and `name2`,
- * `name1 == name2` implies `name1 eq name2`.
+ * @see TermName
+ * @see TypeName
*/
-trait Names extends base.Names {
+trait Names {
+ // Intentionally no implicit from String => Name.
+ implicit def stringToTermName(s: String): TermName = newTermName(s)
+ implicit def stringToTypeName(s: String): TypeName = newTypeName(s)
- /** The abstract type of names */
+ /**
+ * The abstract type of names
+ *
+ * A Name wraps a string as the name for either a type ([[TypeName]]) of a term ([[TermName]]).
+ * Two names are equal, if the wrapped string are equal and they are either both `TypeName` or both `TermName`.
+ * The same string can co-exist as a `TypeName` and a `TermName`, but they would not be equal.
+ * Names are interned. That is, for two names `name11 and `name2`,
+ * `name1 == name2` implies `name1 eq name2`.
+ *
+ * One of the reasons for the existence of names rather than plain strings is being more explicit about what is a name and if it represents a type or a term.
+ */
type Name >: Null <: NameApi
+ implicit val NameTag: ClassTag[Name]
+
+ /** The abstract type of names representing terms */
+ type TypeName >: Null <: Name
+ implicit val TypeNameTag: ClassTag[TypeName]
- /** The extended API of names that's supported on reflect mirror via an
+ /** The abstract type of names representing types */
+ type TermName >: Null <: Name
+ implicit val TermNameTag: ClassTag[TermName]
+
+ /** The API of names that's supported on reflect mirror via an
* implicit conversion in reflect.ops
*/
- abstract class NameApi extends NameBase {
+ abstract class NameApi {
+ /** Checks wether the name is a a term name */
+ def isTermName: Boolean
+
+ /** Checks wether the name is a a type name */
+ def isTypeName: Boolean
+
+ /** Returns a term name that wraps the same string as `this` */
+ def toTermName: TermName
+
+ /** Returns a type name that wraps the same string as `this` */
+ def toTypeName: TypeName
/** Replaces all occurrences of \$op_names in this name by corresponding operator symbols.
* Example: `foo_\$plus\$eq` becomes `foo_+=`
@@ -38,4 +67,20 @@ trait Names extends base.Names {
*/
def encodedName: Name
}
+
+ /** Create a new term name.
+ */
+ def newTermName(s: String): TermName
+
+ /** Creates a new type name.
+ */
+ def newTypeName(s: String): TypeName
+
+ /** Wraps the empty string. Can be used as the null object for term name.
+ */
+ def EmptyTermName: TermName = newTermName("")
+
+ /** Wraps the empty string. Can be used as the null object for type name.
+ */
+ def EmptyTypeName: TypeName = EmptyTermName.toTypeName
}
diff --git a/src/reflect/scala/reflect/api/Positions.scala b/src/reflect/scala/reflect/api/Positions.scala
index 5e8d958f02..0eddc88fc4 100644
--- a/src/reflect/scala/reflect/api/Positions.scala
+++ b/src/reflect/scala/reflect/api/Positions.scala
@@ -1,12 +1,25 @@
package scala.reflect
package api
-trait Positions extends base.Positions {
+/**
+ * Defines the type hierachy for positions.
+ *
+ * @see [[scala.reflect]] for a description on how the class hierarchy is encoded here.
+ */
+trait Positions {
self: Universe =>
/** .. */
type Position >: Null <: PositionApi { type Pos = Position }
+ /** A tag that preserves the identity of the `Position` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val PositionTag: ClassTag[Position]
+
+ /** A special "missing" position. */
+ val NoPosition: Position
+
/** Assigns a given position to all position-less nodes of a given AST.
*/
def atPos[T <: Tree](pos: Position)(tree: T): T
diff --git a/src/reflect/scala/reflect/api/Scopes.scala b/src/reflect/scala/reflect/api/Scopes.scala
new file mode 100644
index 0000000000..d30da07ad5
--- /dev/null
+++ b/src/reflect/scala/reflect/api/Scopes.scala
@@ -0,0 +1,50 @@
+package scala.reflect
+package api
+
+/**
+ * Defines the type hierachy for scopes.
+ *
+ * @see [[scala.reflect]] for a description on how the class hierarchy is encoded here.
+ */
+trait Scopes { self: Universe =>
+
+ /** The base type of all scopes. A scope object generally maps names to symbols available in the current lexical scope.
+ * Scopes can be nested. This base type, however, only exposes a minimal interface, representing a scope as an iterable of symbols.
+ */
+ type Scope >: Null <: ScopeApi
+
+ /** The API that all scopes support */
+ trait ScopeApi extends Iterable[Symbol]
+
+ /** A tag that preserves the identity of the `Scope` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ScopeTag: ClassTag[Scope]
+
+ /** The type of member scopes, as in class definitions, for example. */
+ type MemberScope >: Null <: Scope with MemberScopeApi
+
+ /** The API that all member scopes support */
+ trait MemberScopeApi extends ScopeApi {
+ /** Sorts the symbols included in this scope so that:
+ * 1) Symbols appear in the linearization order of their owners.
+ * 2) Symbols with the same owner appear in reverse order of their declarations.
+ * 3) Synthetic members (e.g. getters/setters for vals/vars) might appear in arbitrary order.
+ */
+ def sorted: List[Symbol]
+ }
+
+ /** A tag that preserves the identity of the `MemberScope` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val MemberScopeTag: ClassTag[MemberScope]
+
+ /** Create a new scope. */
+ def newScope: Scope
+
+ /** Create a new scope nested in another one with which it shares its elements. */
+ def newNestedScope(outer: Scope): Scope
+
+ /** Create a new scope with the given initial elements. */
+ def newScopeWith(elems: Symbol*): Scope
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/api/StandardDefinitions.scala b/src/reflect/scala/reflect/api/StandardDefinitions.scala
index c6f02f1a33..03f2a6b0aa 100644
--- a/src/reflect/scala/reflect/api/StandardDefinitions.scala
+++ b/src/reflect/scala/reflect/api/StandardDefinitions.scala
@@ -5,12 +5,59 @@
package scala.reflect
package api
-trait StandardDefinitions extends base.StandardDefinitions {
+/**
+ * Defines standard symbols and types.
+ */
+trait StandardDefinitions {
self: Universe =>
+ /** A value containing all standard defnitions. */
val definitions: DefinitionsApi
- trait DefinitionsApi extends DefinitionsBase {
+ /** Defines standard symbols (and types via its base trait). */
+ trait DefinitionsApi extends StandardTypes {
+ /** The class symbol of package `scala`. */
+ def ScalaPackageClass: ClassSymbol
+
+ /** The module class symbol of package `scala`. */
+ def ScalaPackage: ModuleSymbol
+
+ // top types
+ def AnyClass : ClassSymbol
+ def AnyValClass: ClassSymbol
+ def ObjectClass: ClassSymbol
+ def AnyRefClass: TypeSymbol
+
+ // bottom types
+ def NullClass : ClassSymbol
+ def NothingClass: ClassSymbol
+
+ // the scala value classes
+ def UnitClass : ClassSymbol
+ def ByteClass : ClassSymbol
+ def ShortClass : ClassSymbol
+ def CharClass : ClassSymbol
+ def IntClass : ClassSymbol
+ def LongClass : ClassSymbol
+ def FloatClass : ClassSymbol
+ def DoubleClass : ClassSymbol
+ def BooleanClass: ClassSymbol
+
+ /** The class symbol of class `String`. */
+ def StringClass : ClassSymbol
+
+ /** The class symbol of class `Class`. */
+ def ClassClass : ClassSymbol
+
+ /** The class symbol of class `Array`. */
+ def ArrayClass : ClassSymbol
+
+ /** The class symbol of class `List`. */
+ def ListClass : ClassSymbol
+
+ /** The module symbol of `scala.Predef`. */
+ def PredefModule: ModuleSymbol
+
def JavaLangPackageClass: ClassSymbol
def JavaLangPackage: ModuleSymbol
def ArrayModule: ModuleSymbol
@@ -45,4 +92,52 @@ trait StandardDefinitions extends base.StandardDefinitions {
def ScalaPrimitiveValueClasses: List[ClassSymbol]
def ScalaNumericValueClasses: List[ClassSymbol]
}
+
+ /** Defines standard types. */
+ trait StandardTypes {
+ /** The `Type` of type `Unit`. */
+ val UnitTpe: Type
+
+ /** The `Type` of primitive type `Byte`. */
+ val ByteTpe: Type
+
+ /** The `Type` of primitive type `Short`. */
+ val ShortTpe: Type
+
+ /** The `Type` of primitive type `Char`. */
+ val CharTpe: Type
+
+ /** The `Type` of primitive type `Int`. */
+ val IntTpe: Type
+
+ /** The `Type` of primitive type `Long`. */
+ val LongTpe: Type
+
+ /** The `Type` of primitive type `Float`. */
+ val FloatTpe: Type
+
+ /** The `Type` of primitive type `Double`. */
+ val DoubleTpe: Type
+
+ /** The `Type` of primitive type `Boolean`. */
+ val BooleanTpe: Type
+
+ /** The `Type` of type `Any`. */
+ val AnyTpe: Type
+
+ /** The `Type` of type `AnyVal`. */
+ val AnyValTpe: Type
+
+ /** The `Type` of type `AnyRef`. */
+ val AnyRefTpe: Type
+
+ /** The `Type` of type `Object`. */
+ val ObjectTpe: Type
+
+ /** The `Type` of type `Nothing`. */
+ val NothingTpe: Type
+
+ /** The `Type` of type `Null`. */
+ val NullTpe: Type
+ }
}
diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala
index 65d87ad7f0..354a9f9328 100644
--- a/src/reflect/scala/reflect/api/StandardNames.scala
+++ b/src/reflect/scala/reflect/api/StandardNames.scala
@@ -5,26 +5,40 @@
package scala.reflect
package api
-// Q: I have a pretty name. Where do I put it - into base.StandardNames or into api.StandardNames?
-// A: <see base.StandardNames>
+// Q: I have a pretty name. Can I put it here?
+// A: Is it necessary to construct trees (like EMPTY or WILDCARD_STAR)? If yes, then sure.
+// Is it necessary to perform reflection (like ERROR or LOCAL_SUFFIX_STRING)? If yes, then sure.
+// Otherwise you'd better not - reflection API should stay minimalistic.
-trait StandardNames extends base.StandardNames {
+// TODO: document better
+/**
+ * Names necessary to create Scala trees.
+ */
+trait StandardNames {
self: Universe =>
val nme: TermNamesApi
val tpnme: TypeNamesApi
- trait NamesApi extends NamesBase {
+ trait NamesApi {
+ type NameType >: Null <: Name
+ val WILDCARD: NameType
val ROOT: NameType
val EMPTY: NameType
val ERROR: NameType
val PACKAGE: NameType
}
- trait TermNamesApi extends NamesApi with TermNamesBase {
+ trait TermNamesApi extends NamesApi {
+ type NameType = TermName
+ val CONSTRUCTOR: NameType
+ val ROOTPKG: NameType
val LOCAL_SUFFIX_STRING: String
}
- trait TypeNamesApi extends NamesApi with TypeNamesBase {
+ trait TypeNamesApi extends NamesApi {
+ type NameType = TypeName
+ val EMPTY: NameType
+ val WILDCARD_STAR: NameType
}
}
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index 0c4be4f7e1..542673ff00 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -1,19 +1,211 @@
package scala.reflect
package api
-trait Symbols extends base.Symbols { self: Universe =>
-
- override type Symbol >: Null <: SymbolApi
- override type TypeSymbol >: Null <: Symbol with TypeSymbolApi
- override type TermSymbol >: Null <: Symbol with TermSymbolApi
- override type MethodSymbol >: Null <: TermSymbol with MethodSymbolApi
- override type ModuleSymbol >: Null <: TermSymbol with ModuleSymbolApi
- override type ClassSymbol >: Null <: TypeSymbol with ClassSymbolApi
- override type FreeTermSymbol >: Null <: TermSymbol with FreeTermSymbolApi
- override type FreeTypeSymbol >: Null <: TypeSymbol with FreeTypeSymbolApi
+/**
+ * Defines the type hierachy for symbols
+ *
+ * @see [[scala.reflect]] for a description on how the class hierarchy is encoded here.
+ */
+trait Symbols { self: Universe =>
+
+ /** The type of symbols representing declarations */
+ type Symbol >: Null <: SymbolApi
+
+ /** A tag that preserves the identity of the `Symbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SymbolTag: ClassTag[Symbol]
+
+ /** The type of type symbols representing type, class, and trait declarations,
+ * as well as type parameters
+ */
+ type TypeSymbol >: Null <: Symbol with TypeSymbolApi
+
+ /** A tag that preserves the identity of the `TypeSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeSymbolTag: ClassTag[TypeSymbol]
+
+ /** The type of term symbols representing val, var, def, and object declarations as
+ * well as packages and value parameters.
+ */
+ type TermSymbol >: Null <: Symbol with TermSymbolApi
+
+ /** A tag that preserves the identity of the `TermSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TermSymbolTag: ClassTag[TermSymbol]
+
+ /** The type of method symbols representing def declarations */
+ type MethodSymbol >: Null <: TermSymbol with MethodSymbolApi
+
+ /** A tag that preserves the identity of the `MethodSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val MethodSymbolTag: ClassTag[MethodSymbol]
+
+ /** The type of module symbols representing object declarations */
+ type ModuleSymbol >: Null <: TermSymbol with ModuleSymbolApi
+
+ /** A tag that preserves the identity of the `ModuleSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ModuleSymbolTag: ClassTag[ModuleSymbol]
+
+ /** The type of class symbols representing class and trait definitions */
+ type ClassSymbol >: Null <: TypeSymbol with ClassSymbolApi
+
+ /** A tag that preserves the identity of the `ClassSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ClassSymbolTag: ClassTag[ClassSymbol]
+
+ /** The type of free terms introduced by reification */
+ type FreeTermSymbol >: Null <: TermSymbol with FreeTermSymbolApi
+
+ /** A tag that preserves the identity of the `FreeTermSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val FreeTermSymbolTag: ClassTag[FreeTermSymbol]
+
+ /** The type of free types introduced by reification */
+ type FreeTypeSymbol >: Null <: TypeSymbol with FreeTypeSymbolApi
+
+ /** A tag that preserves the identity of the `FreeTypeSymbol` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val FreeTypeSymbolTag: ClassTag[FreeTypeSymbol]
+
+ /** A special "missing" symbol */
+ val NoSymbol: Symbol
/** The API of symbols */
- trait SymbolApi extends SymbolBase { this: Symbol =>
+ trait SymbolApi { this: Symbol =>
+
+ /** The owner of this symbol. This is the symbol
+ * that directly contains the current symbol's definition.
+ * The `NoSymbol` symbol does not have an owner, and calling this method
+ * on one causes an internal error.
+ * The owner of the Scala root class [[scala.reflect.api.MirrorOf.RootClass]]
+ * and the Scala root object [[scala.reflect.api.MirrorOf.RootPackage]] is `NoSymbol`.
+ * Every other symbol has a chain of owners that ends in
+ * [[scala.reflect.api.MirrorOf.RootClass]].
+ */
+ def owner: Symbol
+
+ /** The type of the symbol name.
+ * Can be either `TermName` or `TypeName` depending on whether this is a `TermSymbol` or a `TypeSymbol`.
+ *
+ * Type name namespaces do not intersect with term name namespaces.
+ * This fact is reflected in different types for names of `TermSymbol` and `TypeSymbol`.
+ */
+ type NameType >: Null <: Name
+
+ /** The name of the symbol as a member of the `Name` type.
+ */
+ def name: Name
+
+ /** The encoded full path name of this symbol, where outer names and inner names
+ * are separated by periods.
+ */
+ def fullName: String
+
+ /** Does this symbol represent the definition of a type?
+ * Note that every symbol is either a term or a type.
+ * So for every symbol `sym` (except for `NoSymbol`),
+ * either `sym.isTerm` is true or `sym.isType` is true.
+ */
+ def isType: Boolean = false
+
+ /** This symbol cast to a TypeSymbol.
+ * @throws ScalaReflectionException if `isType` is false.
+ */
+ def asType: TypeSymbol = throw new ScalaReflectionException(s"$this is not a type")
+
+ /** Does this symbol represent the definition of a term?
+ * Note that every symbol is either a term or a type.
+ * So for every symbol `sym` (except for `NoSymbol`),
+ * either `sym.isTerm` is true or `sym.isTerm` is true.
+ */
+ def isTerm: Boolean = false
+
+ /** This symbol cast to a TermSymbol.
+ * @throws ScalaReflectionException if `isTerm` is false.
+ */
+ def asTerm: TermSymbol = throw new ScalaReflectionException(s"$this is not a term")
+
+ /** Does this symbol represent the definition of a method?
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isMethod: Boolean = false
+
+ /** This symbol cast to a MethodSymbol.
+ * @throws ScalaReflectionException if `isMethod` is false.
+ */
+ def asMethod: MethodSymbol = {
+ def overloadedMsg =
+ "encapsulates multiple overloaded alternatives and cannot be treated as a method. "+
+ "Consider invoking `<offending symbol>.asTerm.alternatives` and manually picking the required method"
+ def vanillaMsg = "is not a method"
+ val msg = if (isOverloadedMethod) overloadedMsg else vanillaMsg
+ throw new ScalaReflectionException(s"$this $msg")
+ }
+
+ /** Used to provide a better error message for `asMethod` */
+ protected def isOverloadedMethod = false
+
+ /** Does this symbol represent the definition of a module (i.e. it
+ * results from an object definition?).
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isModule: Boolean = false
+
+ /** This symbol cast to a ModuleSymbol defined by an object definition.
+ * @throws ScalaReflectionException if `isModule` is false.
+ */
+ def asModule: ModuleSymbol = throw new ScalaReflectionException(s"$this is not a module")
+
+ /** Does this symbol represent the definition of a class or trait?
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isClass: Boolean = false
+
+ /** Does this symbol represent the definition of a class implicitly associated
+ * with an object definition (module class in scala compiler parlance).
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isModuleClass: Boolean = false
+
+ /** This symbol cast to a ClassSymbol representing a class or trait.
+ * @throws ScalaReflectionException if `isClass` is false.
+ */
+ def asClass: ClassSymbol = throw new ScalaReflectionException(s"$this is not a class")
+
+ /** Does this symbol represent a free term captured by reification?
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isFreeTerm: Boolean = false
+
+ /** This symbol cast to a free term symbol.
+ * @throws ScalaReflectionException if `isFreeTerm` is false.
+ */
+ def asFreeTerm: FreeTermSymbol = throw new ScalaReflectionException(s"$this is not a free term")
+
+ /** Does this symbol represent a free type captured by reification?
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isFreeType: Boolean = false
+
+ /** This symbol cast to a free type symbol.
+ * @throws ScalaReflectionException if `isFreeType` is false.
+ */
+ def asFreeType: FreeTypeSymbol = throw new ScalaReflectionException(s"$this is not a free type")
+
+ def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol
+ def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol)
+ def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol
+ def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol
+ def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol
/** Source file if this symbol is created during this compilation run,
* or a class file if this symbol is loaded from a *.class or *.jar.
@@ -195,7 +387,14 @@ trait Symbols extends base.Symbols { self: Universe =>
}
/** The API of term symbols */
- trait TermSymbolApi extends SymbolApi with TermSymbolBase { this: TermSymbol =>
+ trait TermSymbolApi extends SymbolApi { this: TermSymbol =>
+ /** Term symbols have their names of type `TermName`.
+ */
+ final type NameType = TermName
+
+ final override def isTerm = true
+ final override def asTerm = this
+
/** Is this symbol introduced as `val`?
*/
def isVal: Boolean
@@ -269,7 +468,41 @@ trait Symbols extends base.Symbols { self: Universe =>
}
/** The API of type symbols */
- trait TypeSymbolApi extends SymbolApi with TypeSymbolBase { this: TypeSymbol =>
+ trait TypeSymbolApi extends SymbolApi { this: TypeSymbol =>
+ /** Type symbols have their names of type `TypeName`.
+ */
+ final type NameType = TypeName
+
+ /** The type constructor corresponding to this type symbol.
+ * This is different from `toType` in that type parameters
+ * are part of results of `toType`, but not of `toTypeConstructor`.
+ *
+ * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
+ * `C`. Then `C.toType` is the type `C[T]`, but `C.toTypeConstructor` is `C`.
+ */
+ def toTypeConstructor: Type
+
+ /** A type reference that refers to this type symbol seen
+ * as a member of given type `site`.
+ */
+ def toTypeIn(site: Type): Type
+
+ /** A type reference that refers to this type symbol
+ * Note if symbol is a member of a class, one almost always is interested
+ * in `asTypeIn` with a site type instead.
+ *
+ * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
+ * `C`. Then `C.toType` is the type `C[T]`.
+ *
+ * By contrast, `C.typeSignature` would be a type signature of form
+ * `PolyType(ClassInfoType(...))` that describes type parameters, value
+ * parameters, parent types, and members of `C`.
+ */
+ def toType: Type
+
+ final override def isType = true
+ final override def asType = this
+
/** Is the type parameter represented by this symbol contravariant?
*/
def isContravariant : Boolean
@@ -300,7 +533,10 @@ trait Symbols extends base.Symbols { self: Universe =>
}
/** The API of method symbols */
- trait MethodSymbolApi extends TermSymbolApi with MethodSymbolBase { this: MethodSymbol =>
+ trait MethodSymbolApi extends TermSymbolApi { this: MethodSymbol =>
+ final override def isMethod = true
+ final override def asMethod = this
+
/** Does this method represent a constructor?
*
* If `owner` is a class, then this is a vanilla JVM constructor.
@@ -331,11 +567,23 @@ trait Symbols extends base.Symbols { self: Universe =>
}
/** The API of module symbols */
- trait ModuleSymbolApi extends TermSymbolApi with ModuleSymbolBase { this: ModuleSymbol =>
+ trait ModuleSymbolApi extends TermSymbolApi { this: ModuleSymbol =>
+ /** The class implicitly associated with the object definition.
+ * One can go back from a module class to the associated module symbol
+ * by inspecting its `selfType.termSymbol`.
+ */
+ def moduleClass: Symbol // needed for tree traversals
+ // when this becomes `moduleClass: ClassSymbol`, it will be the happiest day in my life
+
+ final override def isModule = true
+ final override def asModule = this
}
/** The API of class symbols */
- trait ClassSymbolApi extends TypeSymbolApi with ClassSymbolBase { this: ClassSymbol =>
+ trait ClassSymbolApi extends TypeSymbolApi { this: ClassSymbol =>
+ final override def isClass = true
+ final override def asClass = this
+
/** Does this symbol represent the definition of a primitive class?
* Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]],
* [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]?
@@ -398,7 +646,10 @@ trait Symbols extends base.Symbols { self: Universe =>
}
/** The API of free term symbols */
- trait FreeTermSymbolApi extends TermSymbolApi with FreeTermSymbolBase { this: FreeTermSymbol =>
+ trait FreeTermSymbolApi extends TermSymbolApi { this: FreeTermSymbol =>
+ final override def isFreeTerm = true
+ final override def asFreeTerm = this
+
/** The place where this symbol has been spawned */
def origin: String
@@ -407,7 +658,10 @@ trait Symbols extends base.Symbols { self: Universe =>
}
/** The API of free term symbols */
- trait FreeTypeSymbolApi extends TypeSymbolApi with FreeTypeSymbolBase { this: FreeTypeSymbol =>
+ trait FreeTypeSymbolApi extends TypeSymbolApi { this: FreeTypeSymbol =>
+ final override def isFreeType = true
+ final override def asFreeType = this
+
/** The place where this symbol has been spawned */
def origin: String
}
diff --git a/src/reflect/scala/reflect/api/TagInterop.scala b/src/reflect/scala/reflect/api/TagInterop.scala
index 5ab085741e..fc0558d717 100644
--- a/src/reflect/scala/reflect/api/TagInterop.scala
+++ b/src/reflect/scala/reflect/api/TagInterop.scala
@@ -1,32 +1,27 @@
package scala.reflect
package api
-import scala.reflect.base.TypeCreator
-import scala.reflect.base.{Universe => BaseUniverse}
+trait TagInterop { self: Universe =>
+ // TODO `mirror` parameters are now of type `Any`, because I can't make these path-dependent types work
+ // if you're brave enough, replace `Any` with `Mirror`, recompile and run interop_typetags_are_manifests.scala
-trait TagInterop { self: JavaUniverse =>
+ /**
+ * Convert a typetag to a pre `Scala-2.10` manifest.
+ * For example
+ * {{{
+ * typeTagToManifest( scala.reflect.runtime.currentMirror, implicitly[TypeTag[String]] )
+ * }}}
+ */
+ def typeTagToManifest[T: ClassTag](mirror: Any, tag: Universe#TypeTag[T]): Manifest[T] =
+ throw new UnsupportedOperationException("This universe does not support tag -> manifest conversions. Use a JavaUniverse, e.g. the scala.reflect.runtime.universe.")
- override def typeTagToManifest[T: ClassTag](mirror0: Any, tag: base.Universe # TypeTag[T]): Manifest[T] = {
- // SI-6239: make this conversion more precise
- val mirror = mirror0.asInstanceOf[Mirror]
- val runtimeClass = mirror.runtimeClass(tag.in(mirror).tpe)
- Manifest.classType(runtimeClass).asInstanceOf[Manifest[T]]
- }
-
- override def manifestToTypeTag[T](mirror0: Any, manifest: Manifest[T]): base.Universe # TypeTag[T] =
- TypeTag(mirror0.asInstanceOf[Mirror], new TypeCreator {
- def apply[U <: BaseUniverse with Singleton](mirror: MirrorOf[U]): U # Type = {
- mirror.universe match {
- case ju: JavaUniverse =>
- val jm = mirror.asInstanceOf[ju.Mirror]
- val sym = jm.classSymbol(manifest.erasure)
- val tpe =
- if (manifest.typeArguments.isEmpty) sym.toType
- else ju.appliedType(sym.toTypeConstructor, manifest.typeArguments map (targ => ju.manifestToTypeTag(jm, targ)) map (_.in(jm).tpe))
- tpe.asInstanceOf[U # Type]
- case u =>
- u.manifestToTypeTag(mirror.asInstanceOf[u.Mirror], manifest).in(mirror).tpe
- }
- }
- })
+ /**
+ * Convert a pre `Scala-2.10` manifest to a typetag.
+ * For example
+ * {{{
+ * manifestToTypeTag( scala.reflect.runtime.currentMirror, implicitly[Manifest[String]] )
+ * }}}
+ */
+ def manifestToTypeTag[T](mirror: Any, manifest: Manifest[T]): Universe#TypeTag[T] =
+ throw new UnsupportedOperationException("This universe does not support manifest -> tag conversions. Use a JavaUniverse, e.g. the scala.reflect.runtime.universe.")
}
diff --git a/src/reflect/scala/reflect/api/TreeCreator.scala b/src/reflect/scala/reflect/api/TreeCreator.scala
new file mode 100644
index 0000000000..0c8701775c
--- /dev/null
+++ b/src/reflect/scala/reflect/api/TreeCreator.scala
@@ -0,0 +1,26 @@
+package scala.reflect
+package api
+
+/** A mirror-aware factory for trees.
+ *
+ * In the reflection API, artifacts are specific to universes and
+ * symbolic references used in artifacts (e.g. `scala.Int`) are resolved by mirrors.
+ *
+ * Therefore to build a tree one needs to know a universe that the tree is going to be bound to
+ * and a mirror that is going to resolve symbolic references (e.g. to determine that `scala.Int`
+ * points to a core class `Int` from scala-library.jar).
+ *
+ * `TreeCreator` implements this notion by providing a standalone tree factory.
+ *
+ * This is immediately useful for reification. When the compiler reifies an expression,
+ * the end result needs to make sense in any mirror. That's because the compiler knows
+ * the universe it's reifying an expression into (specified by the target of the `reify` call),
+ * but it cannot know in advance the mirror to instantiate the result in (e.g. on JVM
+ * it doesn't know what classloader use to resolve symbolic names in the reifee).
+ *
+ * Due to a typechecker restriction (no eta-expansion for dependent method types),
+ * `TreeCreator` can't have a functional type, so it's implemented as class with an apply method.
+ */
+abstract class TreeCreator {
+ def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Tree
+}
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index 18d960ae04..1f15ee6070 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -6,12 +6,75 @@ package scala.reflect
package api
// Syncnote: Trees are currently not thread-safe.
-trait Trees extends base.Trees { self: Universe =>
+trait Trees { self: Universe =>
+
+ /** Tree is the basis for scala's abstract syntax. The nodes are
+ * implemented as case classes, and the parameters which initialize
+ * a given tree are immutable: however Trees have several mutable
+ * fields which are manipulated in the course of typechecking,
+ * including pos, symbol, and tpe.
+ *
+ * Newly instantiated trees have tpe set to null (though it
+ * may be set immediately thereafter depending on how it is
+ * constructed.) When a tree is passed to the typer, typically via
+ * `typer.typed(tree)`, under normal circumstances the tpe must be
+ * null or the typer will ignore it. Furthermore, the typer is not
+ * required to return the same tree it was passed.
+ *
+ * Trees can be easily traversed with e.g. foreach on the root node;
+ * for a more nuanced traversal, subclass Traverser. Transformations
+ * can be considerably trickier: see the numerous subclasses of
+ * Transformer found around the compiler.
+ *
+ * Copying Trees should be done with care depending on whether
+ * it needs be done lazily or strictly (see LazyTreeCopier and
+ * StrictTreeCopier) and on whether the contents of the mutable
+ * fields should be copied. The tree copiers will copy the mutable
+ * attributes to the new tree; calling Tree#duplicate will copy
+ * symbol and tpe, but all the positions will be focused.
+ *
+ * Trees can be coarsely divided into four mutually exclusive categories:
+ *
+ * - TermTrees, representing terms
+ * - TypTrees, representing types. Note that is `TypTree`, not `TypeTree`.
+ * - SymTrees, which may represent types or terms.
+ * - Other Trees, which have none of those as parents.
+ *
+ * SymTrees include important nodes Ident and Select, which are
+ * used as both terms and types; they are distinguishable based on
+ * whether the Name is a TermName or TypeName. The correct way
+ * to test any Tree for a type or a term are the `isTerm`/`isType`
+ * methods on Tree.
+ *
+ * "Others" are mostly syntactic or short-lived constructs. Examples
+ * include CaseDef, which wraps individual match cases: they are
+ * neither terms nor types, nor do they carry a symbol. Another
+ * example is Parens, which is eliminated during parsing.
+ */
+ type Tree >: Null <: TreeApi
- override type Tree >: Null <: TreeApi
+ /** A tag that preserves the identity of the `Tree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TreeTag: ClassTag[Tree]
- /** ... */
- trait TreeApi extends TreeBase { this: Tree =>
+ /** The API that all trees support */
+ trait TreeApi extends Product { this: Tree =>
+ // TODO
+ /** ... */
+ def isDef: Boolean
+
+ // TODO
+ /** ... */
+ def isEmpty: Boolean
+
+ /** The canonical way to test if a Tree represents a term.
+ */
+ def isTerm: Boolean
+
+ /** The canonical way to test if a Tree represents a type.
+ */
+ def isType: Boolean
/** ... */
def pos: Position
@@ -107,37 +170,83 @@ trait Trees extends base.Trees { self: Universe =>
* in this tree will be found when searching by position).
*/
def duplicate: this.type
+
+ /** Obtains string representation of a tree */
+ override def toString: String = treeToString(this)
}
- override protected def treeType(tree: Tree) = tree.tpe
+ /** Obtains string representation of a tree */
+ protected def treeToString(tree: Tree): String
- override type TermTree >: Null <: Tree with TermTreeApi
+ /** The empty tree */
+ val EmptyTree: Tree
+
+ /** A tree for a term. Not all trees representing terms are TermTrees; use isTerm
+ * to reliably identify terms.
+ */
+ type TermTree >: Null <: AnyRef with Tree with TermTreeApi
+
+ /** A tag that preserves the identity of the `TermTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TermTreeTag: ClassTag[TermTree]
/** The API that all term trees support */
trait TermTreeApi extends TreeApi { this: TermTree =>
}
- override type TypTree >: Null <: Tree with TypTreeApi
+ /** A tree for a type. Not all trees representing types are TypTrees; use isType
+ * to reliably identify types.
+ */
+ type TypTree >: Null <: AnyRef with Tree with TypTreeApi
+
+ /** A tag that preserves the identity of the `TypTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypTreeTag: ClassTag[TypTree]
/** The API that all typ trees support */
trait TypTreeApi extends TreeApi { this: TypTree =>
}
- override type SymTree >: Null <: Tree with SymTreeApi
+ /** A tree with a mutable symbol field, initialized to NoSymbol.
+ */
+ type SymTree >: Null <: AnyRef with Tree with SymTreeApi
+
+ /** A tag that preserves the identity of the `SymTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SymTreeTag: ClassTag[SymTree]
/** The API that all sym trees support */
trait SymTreeApi extends TreeApi { this: SymTree =>
def symbol: Symbol
}
- override type NameTree >: Null <: Tree with NameTreeApi
+ /** A tree with a name - effectively, a DefTree or RefTree.
+ */
+ type NameTree >: Null <: AnyRef with Tree with NameTreeApi
+
+ /** A tag that preserves the identity of the `NameTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val NameTreeTag: ClassTag[NameTree]
/** The API that all name trees support */
trait NameTreeApi extends TreeApi { this: NameTree =>
def name: Name
}
- override type RefTree >: Null <: SymTree with NameTree with RefTreeApi
+ /** A tree which references a symbol-carrying entity.
+ * References one, as opposed to defining one; definitions
+ * are in DefTrees.
+ */
+ type RefTree >: Null <: SymTree with NameTree with RefTreeApi
+
+ /** A tag that preserves the identity of the `RefTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val RefTreeTag: ClassTag[RefTree]
/** The API that all ref trees support */
trait RefTreeApi extends SymTreeApi with NameTreeApi { this: RefTree =>
@@ -145,21 +254,56 @@ trait Trees extends base.Trees { self: Universe =>
def name: Name
}
- override type DefTree >: Null <: SymTree with NameTree with DefTreeApi
+ /** A tree which defines a symbol-carrying entity.
+ */
+ type DefTree >: Null <: SymTree with NameTree with DefTreeApi
+
+ /** A tag that preserves the identity of the `DefTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val DefTreeTag: ClassTag[DefTree]
/** The API that all def trees support */
trait DefTreeApi extends SymTreeApi with NameTreeApi { this: DefTree =>
def name: Name
}
- override type MemberDef >: Null <: DefTree with MemberDefApi
+ /** Common base class for all member definitions: types, classes,
+ * objects, packages, vals and vars, defs.
+ */
+ type MemberDef >: Null <: DefTree with MemberDefApi
+
+ /** A tag that preserves the identity of the `MemberDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val MemberDefTag: ClassTag[MemberDef]
/** The API that all member defs support */
trait MemberDefApi extends DefTreeApi { this: MemberDef =>
def mods: Modifiers
}
- override type PackageDef >: Null <: MemberDef with PackageDefApi
+ /** A packaging, such as `package pid { stats }`
+ */
+ type PackageDef >: Null <: MemberDef with PackageDefApi
+
+ /** A tag that preserves the identity of the `PackageDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val PackageDefTag: ClassTag[PackageDef]
+
+ /** The constructor/deconstructor for `PackageDef` instances. */
+ val PackageDef: PackageDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `PackageDef(pid, stats)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `package` pid { stats }
+ */
+ abstract class PackageDefExtractor {
+ def apply(pid: RefTree, stats: List[Tree]): PackageDef
+ def unapply(packageDef: PackageDef): Option[(RefTree, List[Tree])]
+ }
/** The API that all package defs support */
trait PackageDefApi extends MemberDefApi { this: PackageDef =>
@@ -167,14 +311,45 @@ trait Trees extends base.Trees { self: Universe =>
val stats: List[Tree]
}
- override type ImplDef >: Null <: MemberDef with ImplDefApi
+ /** A common base class for class and object definitions.
+ */
+ type ImplDef >: Null <: MemberDef with ImplDefApi
+
+ /** A tag that preserves the identity of the `ImplDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ImplDefTag: ClassTag[ImplDef]
/** The API that all impl defs support */
trait ImplDefApi extends MemberDefApi { this: ImplDef =>
val impl: Template
}
- override type ClassDef >: Null <: ImplDef with ClassDefApi
+ /** A class definition.
+ */
+ type ClassDef >: Null <: ImplDef with ClassDefApi
+
+ /** A tag that preserves the identity of the `ClassDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ClassDefTag: ClassTag[ClassDef]
+
+ /** The constructor/deconstructor for `ClassDef` instances. */
+ val ClassDef: ClassDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `ClassDef(mods, name, tparams, impl)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * mods `class` name [tparams] impl
+ *
+ * Where impl stands for:
+ *
+ * `extends` parents { defs }
+ */
+ abstract class ClassDefExtractor {
+ def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template): ClassDef
+ def unapply(classDef: ClassDef): Option[(Modifiers, TypeName, List[TypeDef], Template)]
+ }
/** The API that all class defs support */
trait ClassDefApi extends ImplDefApi { this: ClassDef =>
@@ -184,7 +359,33 @@ trait Trees extends base.Trees { self: Universe =>
val impl: Template
}
- override type ModuleDef >: Null <: ImplDef with ModuleDefApi
+ /** An object definition, e.g. `object Foo`. Internally, objects are
+ * quite frequently called modules to reduce ambiguity.
+ * Eliminated by compiler phase refcheck.
+ */
+ type ModuleDef >: Null <: ImplDef with ModuleDefApi
+
+ /** A tag that preserves the identity of the `ModuleDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ModuleDefTag: ClassTag[ModuleDef]
+
+ /** The constructor/deconstructor for `ModuleDef` instances. */
+ val ModuleDef: ModuleDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `ModuleDef(mods, name, impl)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * mods `object` name impl
+ *
+ * Where impl stands for:
+ *
+ * `extends` parents { defs }
+ */
+ abstract class ModuleDefExtractor {
+ def apply(mods: Modifiers, name: TermName, impl: Template): ModuleDef
+ def unapply(moduleDef: ModuleDef): Option[(Modifiers, TermName, Template)]
+ }
/** The API that all module defs support */
trait ModuleDefApi extends ImplDefApi { this: ModuleDef =>
@@ -193,7 +394,14 @@ trait Trees extends base.Trees { self: Universe =>
val impl: Template
}
- override type ValOrDefDef >: Null <: MemberDef with ValOrDefDefApi
+ /** A common base class for ValDefs and DefDefs.
+ */
+ type ValOrDefDef >: Null <: MemberDef with ValOrDefDefApi
+
+ /** A tag that preserves the identity of the `ValOrDefDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ValOrDefDefTag: ClassTag[ValOrDefDef]
/** The API that all val defs and def defs support */
trait ValOrDefDefApi extends MemberDefApi { this: ValOrDefDef =>
@@ -202,7 +410,42 @@ trait Trees extends base.Trees { self: Universe =>
def rhs: Tree
}
- override type ValDef >: Null <: ValOrDefDef with ValDefApi
+ /** Broadly speaking, a value definition. All these are encoded as ValDefs:
+ *
+ * - immutable values, e.g. "val x"
+ * - mutable values, e.g. "var x" - the MUTABLE flag set in mods
+ * - lazy values, e.g. "lazy val x" - the LAZY flag set in mods
+ * - method parameters, see vparamss in [[scala.reflect.api.Trees#DefDef]] - the PARAM flag is set in mods
+ * - explicit self-types, e.g. class A { self: Bar => }
+ */
+ type ValDef >: Null <: ValOrDefDef with ValDefApi
+
+ /** A tag that preserves the identity of the `ValDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ValDefTag: ClassTag[ValDef]
+
+ /** The constructor/deconstructor for `ValDef` instances. */
+ val ValDef: ValDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `ValDef(mods, name, tpt, rhs)`.
+ * This AST node corresponds to any of the following Scala code:
+ *
+ * mods `val` name: tpt = rhs
+ *
+ * mods `var` name: tpt = rhs
+ *
+ * mods name: tpt = rhs // in signatures of function and method definitions
+ *
+ * self: Bar => // self-types
+ *
+ * If the type of a value is not specified explicitly (i.e. is meant to be inferred),
+ * this is expressed by having `tpt` set to `TypeTree()` (but not to an `EmptyTree`!).
+ */
+ abstract class ValDefExtractor {
+ def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree): ValDef
+ def unapply(valDef: ValDef): Option[(Modifiers, TermName, Tree, Tree)]
+ }
/** The API that all val defs support */
trait ValDefApi extends ValOrDefDefApi { this: ValDef =>
@@ -212,7 +455,31 @@ trait Trees extends base.Trees { self: Universe =>
val rhs: Tree
}
- override type DefDef >: Null <: ValOrDefDef with DefDefApi
+ /** A method or macro definition.
+ * @param name The name of the method or macro. Can be a type name in case this is a type macro
+ */
+ type DefDef >: Null <: ValOrDefDef with DefDefApi
+
+ /** A tag that preserves the identity of the `DefDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val DefDefTag: ClassTag[DefDef]
+
+ /** The constructor/deconstructor for `DefDef` instances. */
+ val DefDef: DefDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `DefDef(mods, name, tparams, vparamss, tpt, rhs)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * mods `def` name[tparams](vparams_1)...(vparams_n): tpt = rhs
+ *
+ * If the return type is not specified explicitly (i.e. is meant to be inferred),
+ * this is expressed by having `tpt` set to `TypeTree()` (but not to an `EmptyTree`!).
+ */
+ abstract class DefDefExtractor {
+ def apply(mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef
+ def unapply(defDef: DefDef): Option[(Modifiers, Name, List[TypeDef], List[List[ValDef]], Tree, Tree)]
+ }
/** The API that all def defs support */
trait DefDefApi extends ValOrDefDefApi { this: DefDef =>
@@ -224,7 +491,34 @@ trait Trees extends base.Trees { self: Universe =>
val rhs: Tree
}
- override type TypeDef >: Null <: MemberDef with TypeDefApi
+ /** An abstract type, a type parameter, or a type alias.
+ * Eliminated by erasure.
+ */
+ type TypeDef >: Null <: MemberDef with TypeDefApi
+
+ /** A tag that preserves the identity of the `TypeDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeDefTag: ClassTag[TypeDef]
+
+ /** The constructor/deconstructor for `TypeDef` instances. */
+ val TypeDef: TypeDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeDef(mods, name, tparams, rhs)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * mods `type` name[tparams] = rhs
+ *
+ * mods `type` name[tparams] >: lo <: hi
+ *
+ * First usage illustrates `TypeDefs` representing type aliases and type parameters.
+ * Second usage illustrates `TypeDefs` representing abstract types,
+ * where lo and hi are both `TypeBoundsTrees` and `Modifier.deferred` is set in mods.
+ */
+ abstract class TypeDefExtractor {
+ def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree): TypeDef
+ def unapply(typeDef: TypeDef): Option[(Modifiers, TypeName, List[TypeDef], Tree)]
+ }
/** The API that all type defs support */
trait TypeDefApi extends MemberDefApi { this: TypeDef =>
@@ -234,7 +528,46 @@ trait Trees extends base.Trees { self: Universe =>
val rhs: Tree
}
- override type LabelDef >: Null <: DefTree with TermTree with LabelDefApi
+ /** A labelled expression. Not expressible in language syntax, but
+ * generated by the compiler to simulate while/do-while loops, and
+ * also by the pattern matcher.
+ *
+ * The label acts much like a nested function, where `params` represents
+ * the incoming parameters. The symbol given to the LabelDef should have
+ * a MethodType, as if it were a nested function.
+ *
+ * Jumps are apply nodes attributed with a label's symbol. The
+ * arguments from the apply node will be passed to the label and
+ * assigned to the Idents.
+ *
+ * Forward jumps within a block are allowed.
+ */
+ type LabelDef >: Null <: DefTree with TermTree with LabelDefApi
+
+ /** A tag that preserves the identity of the `LabelDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val LabelDefTag: ClassTag[LabelDef]
+
+ /** The constructor/deconstructor for `LabelDef` instances. */
+ val LabelDef: LabelDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `LabelDef(name, params, rhs)`.
+ *
+ * This AST node does not have direct correspondence to Scala code.
+ * It is used for tailcalls and like.
+ * For example, while/do are desugared to label defs as follows:
+ * {{{
+ * while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else ())
+ * }}}
+ * {{{
+ * do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else ())
+ * }}}
+ */
+ abstract class LabelDefExtractor {
+ def apply(name: TermName, params: List[Ident], rhs: Tree): LabelDef
+ def unapply(labelDef: LabelDef): Option[(TermName, List[Ident], Tree)]
+ }
/** The API that all label defs support */
trait LabelDefApi extends DefTreeApi with TermTreeApi { this: LabelDef =>
@@ -243,7 +576,34 @@ trait Trees extends base.Trees { self: Universe =>
val rhs: Tree
}
- override type ImportSelector >: Null <: ImportSelectorApi
+ /** Import selector
+ *
+ * Representation of an imported name its optional rename and their optional positions
+ *
+ * Eliminated by typecheck.
+ *
+ * @param name the imported name
+ * @param namePos its position or -1 if undefined
+ * @param rename the name the import is renamed to (== name if no renaming)
+ * @param renamePos the position of the rename or -1 if undefined
+ */
+ type ImportSelector >: Null <: AnyRef with ImportSelectorApi
+
+ /** A tag that preserves the identity of the `ImportSelector` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ImportSelectorTag: ClassTag[ImportSelector]
+
+ /** The constructor/deconstructor for `ImportSelector` instances. */
+ val ImportSelector: ImportSelectorExtractor
+
+ /** An extractor class to create and pattern match with syntax `ImportSelector(name:, namePos, rename, renamePos)`.
+ * This is not an AST node, it is used as a part of the `Import` node.
+ */
+ abstract class ImportSelectorExtractor {
+ def apply(name: Name, namePos: Int, rename: Name, renamePos: Int): ImportSelector
+ def unapply(importSelector: ImportSelector): Option[(Name, Int, Name, Int)]
+ }
/** The API that all import selectors support */
trait ImportSelectorApi { this: ImportSelector =>
@@ -253,7 +613,42 @@ trait Trees extends base.Trees { self: Universe =>
val renamePos: Int
}
- override type Import >: Null <: SymTree with ImportApi
+ /** Import clause
+ *
+ * @param expr
+ * @param selectors
+ */
+ type Import >: Null <: SymTree with ImportApi
+
+ /** A tag that preserves the identity of the `Import` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ImportTag: ClassTag[Import]
+
+ /** The constructor/deconstructor for `Import` instances. */
+ val Import: ImportExtractor
+
+ /** An extractor class to create and pattern match with syntax `Import(expr, selectors)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * import expr.{selectors}
+ *
+ * Selectors are a list of ImportSelectors, which conceptually are pairs of names (from, to).
+ * The last (and maybe only name) may be a nme.WILDCARD. For instance:
+ *
+ * import qual.{x, y => z, _}
+ *
+ * Would be represented as:
+ *
+ * Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null)))
+ *
+ * The symbol of an `Import` is an import symbol @see Symbol.newImport.
+ * It's used primarily as a marker to check that the import has been typechecked.
+ */
+ abstract class ImportExtractor {
+ def apply(expr: Tree, selectors: List[ImportSelector]): Import
+ def unapply(import_ : Import): Option[(Tree, List[ImportSelector])]
+ }
/** The API that all imports support */
trait ImportApi extends SymTreeApi { this: Import =>
@@ -261,7 +656,43 @@ trait Trees extends base.Trees { self: Universe =>
val selectors: List[ImportSelector]
}
- override type Template >: Null <: SymTree with TemplateApi
+ /** Instantiation template of a class or trait
+ *
+ * @param parents
+ * @param body
+ */
+ type Template >: Null <: SymTree with TemplateApi
+
+ /** A tag that preserves the identity of the `Template` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TemplateTag: ClassTag[Template]
+
+ /** The constructor/deconstructor for `Template` instances. */
+ val Template: TemplateExtractor
+
+ /** An extractor class to create and pattern match with syntax `Template(parents, self, body)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `extends` parents { self => body }
+ *
+ * In case when the self-type annotation is missing, it is represented as
+ * an empty value definition with nme.WILDCARD as name and NoType as type.
+ *
+ * The symbol of a template is a local dummy. @see Symbol.newLocalDummy
+ * The owner of the local dummy is the enclosing trait or class.
+ * The local dummy is itself the owner of any local blocks. For example:
+ *
+ * class C {
+ * def foo { // owner is C
+ * def bar // owner is local dummy
+ * }
+ * }
+ */
+ abstract class TemplateExtractor {
+ def apply(parents: List[Tree], self: ValDef, body: List[Tree]): Template
+ def unapply(template: Template): Option[(List[Tree], ValDef, List[Tree])]
+ }
/** The API that all templates support */
trait TemplateApi extends SymTreeApi { this: Template =>
@@ -270,7 +701,28 @@ trait Trees extends base.Trees { self: Universe =>
val body: List[Tree]
}
- override type Block >: Null <: TermTree with BlockApi
+ /** Block of expressions (semicolon separated expressions) */
+ type Block >: Null <: TermTree with BlockApi
+
+ /** A tag that preserves the identity of the `Block` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val BlockTag: ClassTag[Block]
+
+ /** The constructor/deconstructor for `Block` instances. */
+ val Block: BlockExtractor
+
+ /** An extractor class to create and pattern match with syntax `Block(stats, expr)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * { stats; expr }
+ *
+ * If the block is empty, the `expr` is set to `Literal(Constant(()))`.
+ */
+ abstract class BlockExtractor {
+ def apply(stats: List[Tree], expr: Tree): Block
+ def unapply(block: Block): Option[(List[Tree], Tree)]
+ }
/** The API that all blocks support */
trait BlockApi extends TermTreeApi { this: Block =>
@@ -278,7 +730,32 @@ trait Trees extends base.Trees { self: Universe =>
val expr: Tree
}
- override type CaseDef >: Null <: Tree with CaseDefApi
+ /** Case clause in a pattern match.
+ * (except for occurrences in switch statements).
+ * Eliminated by compiler phases patmat (in the new pattern matcher of 2.10) or explicitouter (in the old pre-2.10 pattern matcher)
+ */
+ type CaseDef >: Null <: AnyRef with Tree with CaseDefApi
+
+ /** A tag that preserves the identity of the `CaseDef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val CaseDefTag: ClassTag[CaseDef]
+
+ /** The constructor/deconstructor for `CaseDef` instances. */
+ val CaseDef: CaseDefExtractor
+
+ /** An extractor class to create and pattern match with syntax `CaseDef(pat, guard, body)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `case` pat `if` guard => body
+ *
+ * If the guard is not present, the `guard` is set to `EmptyTree`.
+ * If the body is not specified, the `body` is set to `Literal(Constant())`
+ */
+ abstract class CaseDefExtractor {
+ def apply(pat: Tree, guard: Tree, body: Tree): CaseDef
+ def unapply(caseDef: CaseDef): Option[(Tree, Tree, Tree)]
+ }
/** The API that all case defs support */
trait CaseDefApi extends TreeApi { this: CaseDef =>
@@ -287,21 +764,92 @@ trait Trees extends base.Trees { self: Universe =>
val body: Tree
}
- override type Alternative >: Null <: TermTree with AlternativeApi
+ /** Alternatives of patterns.
+ *
+ * Eliminated by compiler phases Eliminated by compiler phases patmat (in the new pattern matcher of 2.10) or explicitouter (in the old pre-2.10 pattern matcher),
+ * except for
+ * occurrences in encoded Switch stmt (i.e. remaining Match(CaseDef(...)))
+ */
+ type Alternative >: Null <: TermTree with AlternativeApi
+
+ /** A tag that preserves the identity of the `Alternative` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AlternativeTag: ClassTag[Alternative]
+
+ /** The constructor/deconstructor for `Alternative` instances. */
+ val Alternative: AlternativeExtractor
+
+ /** An extractor class to create and pattern match with syntax `Alternative(trees)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * pat1 | ... | patn
+ */
+ abstract class AlternativeExtractor {
+ def apply(trees: List[Tree]): Alternative
+ def unapply(alternative: Alternative): Option[List[Tree]]
+ }
/** The API that all alternatives support */
trait AlternativeApi extends TermTreeApi { this: Alternative =>
val trees: List[Tree]
}
- override type Star >: Null <: TermTree with StarApi
+ /** Repetition of pattern.
+ *
+ * Eliminated by compiler phases patmat (in the new pattern matcher of 2.10) or explicitouter (in the old pre-2.10 pattern matcher).
+ */
+ type Star >: Null <: TermTree with StarApi
+
+ /** A tag that preserves the identity of the `Star` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val StarTag: ClassTag[Star]
+
+ /** The constructor/deconstructor for `Star` instances. */
+ val Star: StarExtractor
+
+ /** An extractor class to create and pattern match with syntax `Star(elem)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * pat*
+ */
+ abstract class StarExtractor {
+ def apply(elem: Tree): Star
+ def unapply(star: Star): Option[Tree]
+ }
/** The API that all stars support */
trait StarApi extends TermTreeApi { this: Star =>
val elem: Tree
}
- override type Bind >: Null <: DefTree with BindApi
+ /** Bind a variable to a rhs pattern.
+ *
+ * Eliminated by compiler phases patmat (in the new pattern matcher of 2.10) or explicitouter (in the old pre-2.10 pattern matcher).
+ *
+ * @param name
+ * @param body
+ */
+ type Bind >: Null <: DefTree with BindApi
+
+ /** A tag that preserves the identity of the `Bind` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val BindTag: ClassTag[Bind]
+
+ /** The constructor/deconstructor for `Bind` instances. */
+ val Bind: BindExtractor
+
+ /** An extractor class to create and pattern match with syntax `Bind(name, body)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * pat*
+ */
+ abstract class BindExtractor {
+ def apply(name: Name, body: Tree): Bind
+ def unapply(bind: Bind): Option[(Name, Tree)]
+ }
/** The API that all binds support */
trait BindApi extends DefTreeApi { this: Bind =>
@@ -309,7 +857,51 @@ trait Trees extends base.Trees { self: Universe =>
val body: Tree
}
- override type UnApply >: Null <: TermTree with UnApplyApi
+ /**
+ * Used to represent `unapply` methods in pattern matching.
+ *
+ * For example:
+ * {{{
+ * 2 match { case Foo(x) => x }
+ * }}}
+ *
+ * Is represented as:
+ * {{{
+ * Match(
+ * Literal(Constant(2)),
+ * List(
+ * CaseDef(
+ * UnApply(
+ * // a dummy node that carries the type of unapplication to patmat
+ * // the <unapply-selector> here doesn't have an underlying symbol
+ * // it only has a type assigned, therefore after `resetAllAttrs` this tree is no longer typeable
+ * Apply(Select(Ident(Foo), newTermName("unapply")), List(Ident(newTermName("<unapply-selector>")))),
+ * // arguments of the unapply => nothing synthetic here
+ * List(Bind(newTermName("x"), Ident(nme.WILDCARD)))),
+ * EmptyTree,
+ * Ident(newTermName("x")))))
+ * }}}
+ *
+ * Introduced by typer. Eliminated by compiler phases patmat (in the new pattern matcher of 2.10) or explicitouter (in the old pre-2.10 pattern matcher).
+ */
+ type UnApply >: Null <: TermTree with UnApplyApi
+
+ /** A tag that preserves the identity of the `UnApply` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val UnApplyTag: ClassTag[UnApply]
+
+ /** The constructor/deconstructor for `UnApply` instances. */
+ val UnApply: UnApplyExtractor
+
+ /** An extractor class to create and pattern match with syntax `UnApply(fun, args)`.
+ * This AST node does not have direct correspondence to Scala code,
+ * and is introduced when typechecking pattern matches and `try` blocks.
+ */
+ abstract class UnApplyExtractor {
+ def apply(fun: Tree, args: List[Tree]): UnApply
+ def unapply(unApply: UnApply): Option[(Tree, List[Tree])]
+ }
/** The API that all unapplies support */
trait UnApplyApi extends TermTreeApi { this: UnApply =>
@@ -317,7 +909,29 @@ trait Trees extends base.Trees { self: Universe =>
val args: List[Tree]
}
- override type Function >: Null <: TermTree with SymTree with FunctionApi
+ /** Anonymous function, eliminated by compiler phase lambdalift */
+ type Function >: Null <: TermTree with SymTree with FunctionApi
+
+ /** A tag that preserves the identity of the `Function` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val FunctionTag: ClassTag[Function]
+
+ /** The constructor/deconstructor for `Function` instances. */
+ val Function: FunctionExtractor
+
+ /** An extractor class to create and pattern match with syntax `Function(vparams, body)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * vparams => body
+ *
+ * The symbol of a Function is a synthetic TermSymbol.
+ * It is the owner of the function's parameters.
+ */
+ abstract class FunctionExtractor {
+ def apply(vparams: List[ValDef], body: Tree): Function
+ def unapply(function: Function): Option[(List[ValDef], Tree)]
+ }
/** The API that all functions support */
trait FunctionApi extends TermTreeApi with SymTreeApi { this: Function =>
@@ -325,7 +939,26 @@ trait Trees extends base.Trees { self: Universe =>
val body: Tree
}
- override type Assign >: Null <: TermTree with AssignApi
+ /** Assignment */
+ type Assign >: Null <: TermTree with AssignApi
+
+ /** A tag that preserves the identity of the `Assign` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AssignTag: ClassTag[Assign]
+
+ /** The constructor/deconstructor for `Assign` instances. */
+ val Assign: AssignExtractor
+
+ /** An extractor class to create and pattern match with syntax `Assign(lhs, rhs)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * lhs = rhs
+ */
+ abstract class AssignExtractor {
+ def apply(lhs: Tree, rhs: Tree): Assign
+ def unapply(assign: Assign): Option[(Tree, Tree)]
+ }
/** The API that all assigns support */
trait AssignApi extends TermTreeApi { this: Assign =>
@@ -333,7 +966,34 @@ trait Trees extends base.Trees { self: Universe =>
val rhs: Tree
}
- override type AssignOrNamedArg >: Null <: TermTree with AssignOrNamedArgApi
+ /** Either an assignment or a named argument. Only appears in argument lists,
+ * eliminated by compiler phase typecheck (doTypedApply), resurrected by reifier.
+ */
+ type AssignOrNamedArg >: Null <: TermTree with AssignOrNamedArgApi
+
+ /** A tag that preserves the identity of the `AssignOrNamedArg` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AssignOrNamedArgTag: ClassTag[AssignOrNamedArg]
+
+ /** The constructor/deconstructor for `AssignOrNamedArg` instances. */
+ val AssignOrNamedArg: AssignOrNamedArgExtractor
+
+ /** An extractor class to create and pattern match with syntax `AssignOrNamedArg(lhs, rhs)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * {{{
+ * m.f(lhs = rhs)
+ * }}}
+ * {{{
+ * @annotation(lhs = rhs)
+ * }}}
+ *
+ */
+ abstract class AssignOrNamedArgExtractor {
+ def apply(lhs: Tree, rhs: Tree): AssignOrNamedArg
+ def unapply(assignOrNamedArg: AssignOrNamedArg): Option[(Tree, Tree)]
+ }
/** The API that all assigns support */
trait AssignOrNamedArgApi extends TermTreeApi { this: AssignOrNamedArg =>
@@ -341,7 +1001,28 @@ trait Trees extends base.Trees { self: Universe =>
val rhs: Tree
}
- override type If >: Null <: TermTree with IfApi
+ /** Conditional expression */
+ type If >: Null <: TermTree with IfApi
+
+ /** A tag that preserves the identity of the `If` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val IfTag: ClassTag[If]
+
+ /** The constructor/deconstructor for `If` instances. */
+ val If: IfExtractor
+
+ /** An extractor class to create and pattern match with syntax `If(cond, thenp, elsep)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `if` (cond) thenp `else` elsep
+ *
+ * If the alternative is not present, the `elsep` is set to `Literal(Constant(()))`.
+ */
+ abstract class IfExtractor {
+ def apply(cond: Tree, thenp: Tree, elsep: Tree): If
+ def unapply(if_ : If): Option[(Tree, Tree, Tree)]
+ }
/** The API that all ifs support */
trait IfApi extends TermTreeApi { this: If =>
@@ -350,7 +1031,38 @@ trait Trees extends base.Trees { self: Universe =>
val elsep: Tree
}
- override type Match >: Null <: TermTree with MatchApi
+ /** - Pattern matching expression (before compiler phase explicitouter before 2.10 / patmat from 2.10)
+ * - Switch statements (after compiler phase explicitouter before 2.10 / patmat from 2.10)
+ *
+ * After compiler phase explicitouter before 2.10 / patmat from 2.10, cases will satisfy the following constraints:
+ *
+ * - all guards are `EmptyTree`,
+ * - all patterns will be either `Literal(Constant(x:Int))`
+ * or `Alternative(lit|...|lit)`
+ * - except for an "otherwise" branch, which has pattern
+ * `Ident(nme.WILDCARD)`
+ */
+ type Match >: Null <: TermTree with MatchApi
+
+ /** A tag that preserves the identity of the `Match` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val MatchTag: ClassTag[Match]
+
+ /** The constructor/deconstructor for `Match` instances. */
+ val Match: MatchExtractor
+
+ /** An extractor class to create and pattern match with syntax `Match(selector, cases)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * selector `match` { cases }
+ *
+ * `Match` is also used in pattern matching assignments like `val (foo, bar) = baz`.
+ */
+ abstract class MatchExtractor {
+ def apply(selector: Tree, cases: List[CaseDef]): Match
+ def unapply(match_ : Match): Option[(Tree, List[CaseDef])]
+ }
/** The API that all matches support */
trait MatchApi extends TermTreeApi { this: Match =>
@@ -358,14 +1070,56 @@ trait Trees extends base.Trees { self: Universe =>
val cases: List[CaseDef]
}
- override type Return >: Null <: TermTree with SymTree with ReturnApi
+ /** Return expression */
+ type Return >: Null <: TermTree with SymTree with ReturnApi
+
+ /** A tag that preserves the identity of the `Return` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ReturnTag: ClassTag[Return]
+
+ /** The constructor/deconstructor for `Return` instances. */
+ val Return: ReturnExtractor
+
+ /** An extractor class to create and pattern match with syntax `Return(expr)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `return` expr
+ *
+ * The symbol of a Return node is the enclosing method.
+ */
+ abstract class ReturnExtractor {
+ def apply(expr: Tree): Return
+ def unapply(return_ : Return): Option[Tree]
+ }
/** The API that all returns support */
trait ReturnApi extends TermTreeApi { this: Return =>
val expr: Tree
}
- override type Try >: Null <: TermTree with TryApi
+ /** [Eugene++] comment me! */
+ type Try >: Null <: TermTree with TryApi
+
+ /** A tag that preserves the identity of the `Try` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TryTag: ClassTag[Try]
+
+ /** The constructor/deconstructor for `Try` instances. */
+ val Try: TryExtractor
+
+ /** An extractor class to create and pattern match with syntax `Try(block, catches, finalizer)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `try` block `catch` { catches } `finally` finalizer
+ *
+ * If the finalizer is not present, the `finalizer` is set to `EmptyTree`.
+ */
+ abstract class TryExtractor {
+ def apply(block: Tree, catches: List[CaseDef], finalizer: Tree): Try
+ def unapply(try_ : Try): Option[(Tree, List[CaseDef], Tree)]
+ }
/** The API that all tries support */
trait TryApi extends TermTreeApi { this: Try =>
@@ -374,21 +1128,89 @@ trait Trees extends base.Trees { self: Universe =>
val finalizer: Tree
}
- override type Throw >: Null <: TermTree with ThrowApi
+ /** Throw expression */
+ type Throw >: Null <: TermTree with ThrowApi
+
+ /** A tag that preserves the identity of the `Throw` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ThrowTag: ClassTag[Throw]
+
+ /** The constructor/deconstructor for `Throw` instances. */
+ val Throw: ThrowExtractor
+
+ /** An extractor class to create and pattern match with syntax `Throw(expr)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `throw` expr
+ */
+ abstract class ThrowExtractor {
+ def apply(expr: Tree): Throw
+ def unapply(throw_ : Throw): Option[Tree]
+ }
/** The API that all tries support */
trait ThrowApi extends TermTreeApi { this: Throw =>
val expr: Tree
}
- override type New >: Null <: TermTree with NewApi
+ /** Object instantiation
+ */
+ type New >: Null <: TermTree with NewApi
+
+ /** A tag that preserves the identity of the `New` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val NewTag: ClassTag[New]
+
+ /** The constructor/deconstructor for `New` instances.
+ */
+ val New: NewExtractor
+
+ /** An extractor class to create and pattern match with syntax `New(tpt)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * `new` T
+ *
+ * This node always occurs in the following context:
+ *
+ * (`new` tpt).<init>[targs](args)
+ */
+ abstract class NewExtractor {
+ /** A user level `new`.
+ * One should always use this factory method to build a user level `new`.
+ *
+ * @param tpt a class type
+ */
+ def apply(tpt: Tree): New
+ def unapply(new_ : New): Option[Tree]
+ }
/** The API that all news support */
trait NewApi extends TermTreeApi { this: New =>
val tpt: Tree
}
- override type Typed >: Null <: TermTree with TypedApi
+ /** Type annotation, eliminated by compiler phase cleanup */
+ type Typed >: Null <: TermTree with TypedApi
+
+ /** A tag that preserves the identity of the `Typed` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypedTag: ClassTag[Typed]
+
+ /** The constructor/deconstructor for `Typed` instances. */
+ val Typed: TypedExtractor
+
+ /** An extractor class to create and pattern match with syntax `Typed(expr, tpt)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * expr: tpt
+ */
+ abstract class TypedExtractor {
+ def apply(expr: Tree, tpt: Tree): Typed
+ def unapply(typed: Typed): Option[(Tree, Tree)]
+ }
/** The API that all typeds support */
trait TypedApi extends TermTreeApi { this: Typed =>
@@ -396,7 +1218,14 @@ trait Trees extends base.Trees { self: Universe =>
val tpt: Tree
}
- override type GenericApply >: Null <: TermTree with GenericApplyApi
+ /** Common base class for Apply and TypeApply.
+ */
+ type GenericApply >: Null <: TermTree with GenericApplyApi
+
+ /** A tag that preserves the identity of the `GenericApply` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val GenericApplyTag: ClassTag[GenericApply]
/** The API that all applies support */
trait GenericApplyApi extends TermTreeApi { this: GenericApply =>
@@ -404,19 +1233,99 @@ trait Trees extends base.Trees { self: Universe =>
val args: List[Tree]
}
- override type TypeApply >: Null <: GenericApply with TypeApplyApi
+ /* @PP: All signs point toward it being a requirement that args.nonEmpty,
+ * but I can't find that explicitly stated anywhere. Unless your last name
+ * is odersky, you should probably treat it as true.
+ */
+ /** Explicit type application. */
+ type TypeApply >: Null <: GenericApply with TypeApplyApi
+
+ /** A tag that preserves the identity of the `TypeApply` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeApplyTag: ClassTag[TypeApply]
+
+ /** The constructor/deconstructor for `TypeApply` instances. */
+ val TypeApply: TypeApplyExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeApply(fun, args)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * fun[args]
+ */
+ abstract class TypeApplyExtractor {
+ def apply(fun: Tree, args: List[Tree]): TypeApply
+ def unapply(typeApply: TypeApply): Option[(Tree, List[Tree])]
+ }
/** The API that all type applies support */
trait TypeApplyApi extends GenericApplyApi { this: TypeApply =>
}
- override type Apply >: Null <: GenericApply with ApplyApi
+ /** Value application */
+ type Apply >: Null <: GenericApply with ApplyApi
+
+ /** A tag that preserves the identity of the `Apply` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ApplyTag: ClassTag[Apply]
+
+ /** The constructor/deconstructor for `Apply` instances. */
+ val Apply: ApplyExtractor
+
+ /** An extractor class to create and pattern match with syntax `Apply(fun, args)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * fun(args)
+ *
+ * For instance:
+ *
+ * fun[targs](args)
+ *
+ * Is expressed as:
+ *
+ * Apply(TypeApply(fun, targs), args)
+ */
+ abstract class ApplyExtractor {
+ def apply(fun: Tree, args: List[Tree]): Apply
+ def unapply(apply: Apply): Option[(Tree, List[Tree])]
+ }
/** The API that all applies support */
trait ApplyApi extends GenericApplyApi { this: Apply =>
}
- override type Super >: Null <: TermTree with SuperApi
+ /** Super reference, where `qual` is the corresponding `this` reference.
+ * A super reference `C.super[M]` is represented as `Super(This(C), M)`.
+ */
+ type Super >: Null <: TermTree with SuperApi
+
+ /** A tag that preserves the identity of the `Super` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SuperTag: ClassTag[Super]
+
+ /** The constructor/deconstructor for `Super` instances. */
+ val Super: SuperExtractor
+
+ /** An extractor class to create and pattern match with syntax `Super(qual, mix)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * C.super[M]
+ *
+ * Which is represented as:
+ *
+ * Super(This(C), M)
+ *
+ * If `mix` is empty, it is tpnme.EMPTY.
+ *
+ * The symbol of a Super is the class _from_ which the super reference is made.
+ * For instance in C.super(...), it would be C.
+ */
+ abstract class SuperExtractor {
+ def apply(qual: Tree, mix: TypeName): Super
+ def unapply(super_ : Super): Option[(Tree, TypeName)]
+ }
/** The API that all supers support */
trait SuperApi extends TermTreeApi { this: Super =>
@@ -424,14 +1333,57 @@ trait Trees extends base.Trees { self: Universe =>
val mix: TypeName
}
- override type This >: Null <: TermTree with SymTree with ThisApi
+ /** Self reference */
+ type This >: Null <: TermTree with SymTree with ThisApi
+
+ /** A tag that preserves the identity of the `This` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ThisTag: ClassTag[This]
+
+ /** The constructor/deconstructor for `This` instances. */
+ val This: ThisExtractor
+
+ /** An extractor class to create and pattern match with syntax `This(qual)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * qual.this
+ *
+ * The symbol of a This is the class to which the this refers.
+ * For instance in C.this, it would be C.
+ *
+ * If `mix` is empty, then ???
+ */
+ abstract class ThisExtractor {
+ def apply(qual: TypeName): This
+ def unapply(this_ : This): Option[TypeName]
+ }
/** The API that all thises support */
trait ThisApi extends TermTreeApi with SymTreeApi { this: This =>
val qual: TypeName
}
- override type Select >: Null <: RefTree with SelectApi
+ /** Designator <qualifier> . <name> */
+ type Select >: Null <: RefTree with SelectApi
+
+ /** A tag that preserves the identity of the `Select` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SelectTag: ClassTag[Select]
+
+ /** The constructor/deconstructor for `Select` instances. */
+ val Select: SelectExtractor
+
+ /** An extractor class to create and pattern match with syntax `Select(qual, name)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * qualifier.selector
+ */
+ abstract class SelectExtractor {
+ def apply(qualifier: Tree, name: Name): Select
+ def unapply(select: Select): Option[(Tree, Name)]
+ }
/** The API that all selects support */
trait SelectApi extends RefTreeApi { this: Select =>
@@ -439,28 +1391,132 @@ trait Trees extends base.Trees { self: Universe =>
val name: Name
}
- override type Ident >: Null <: RefTree with IdentApi
+ /** Identifier <name> */
+ type Ident >: Null <: RefTree with IdentApi
+
+ /** A tag that preserves the identity of the `Ident` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val IdentTag: ClassTag[Ident]
+
+ /** The constructor/deconstructor for `Ident` instances. */
+ val Ident: IdentExtractor
+
+ /** An extractor class to create and pattern match with syntax `Ident(qual, name)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * name
+ *
+ * Type checker converts idents that refer to enclosing fields or methods to selects.
+ * For example, name ==> this.name
+ */
+ abstract class IdentExtractor {
+ def apply(name: Name): Ident
+ def unapply(ident: Ident): Option[Name]
+ }
/** The API that all idents support */
trait IdentApi extends RefTreeApi { this: Ident =>
val name: Name
}
- override type ReferenceToBoxed >: Null <: TermTree with ReferenceToBoxedApi
+ /** Marks underlying reference to id as boxed.
+ * @pre id must refer to a captured variable
+ * A reference such marked will refer to the boxed entity, no dereferencing
+ * with `.elem` is done on it.
+ * This tree node can be emitted by macros such as reify that call referenceCapturedVariable.
+ * It is eliminated in LambdaLift, where the boxing conversion takes place.
+ */
+ type ReferenceToBoxed >: Null <: TermTree with ReferenceToBoxedApi
+
+ /** A tag that preserves the identity of the `ReferenceToBoxed` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ReferenceToBoxedTag: ClassTag[ReferenceToBoxed]
+
+ /** The constructor/deconstructor for `ReferenceToBoxed` instances. */
+ val ReferenceToBoxed: ReferenceToBoxedExtractor
+
+ /** An extractor class to create and pattern match with syntax `ReferenceToBoxed(ident)`.
+ * This AST node does not have direct correspondence to Scala code,
+ * and is emitted by macros to reference capture vars directly without going through `elem`.
+ *
+ * For example:
+ *
+ * var x = ...
+ * fun { x }
+ *
+ * Will emit:
+ *
+ * Ident(x)
+ *
+ * Which gets transformed to:
+ *
+ * Select(Ident(x), "elem")
+ *
+ * If `ReferenceToBoxed` were used instead of Ident, no transformation would be performed.
+ */
+ abstract class ReferenceToBoxedExtractor {
+ def apply(ident: Ident): ReferenceToBoxed
+ def unapply(referenceToBoxed: ReferenceToBoxed): Option[Ident]
+ }
/** The API that all references support */
trait ReferenceToBoxedApi extends TermTreeApi { this: ReferenceToBoxed =>
val ident: Tree
}
- override type Literal >: Null <: TermTree with LiteralApi
+ /** Literal */
+ type Literal >: Null <: TermTree with LiteralApi
+
+ /** A tag that preserves the identity of the `Literal` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val LiteralTag: ClassTag[Literal]
+
+ /** The constructor/deconstructor for `Literal` instances. */
+ val Literal: LiteralExtractor
+
+ /** An extractor class to create and pattern match with syntax `Literal(value)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * value
+ */
+ abstract class LiteralExtractor {
+ def apply(value: Constant): Literal
+ def unapply(literal: Literal): Option[Constant]
+ }
/** The API that all literals support */
trait LiteralApi extends TermTreeApi { this: Literal =>
val value: Constant
}
- override type Annotated >: Null <: Tree with AnnotatedApi
+ /** A tree that has an annotation attached to it. Only used for annotated types and
+ * annotation ascriptions, annotations on definitions are stored in the Modifiers.
+ * Eliminated by typechecker (typedAnnotated), the annotations are then stored in
+ * an AnnotatedType.
+ */
+ type Annotated >: Null <: AnyRef with Tree with AnnotatedApi
+
+ /** A tag that preserves the identity of the `Annotated` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AnnotatedTag: ClassTag[Annotated]
+
+ /** The constructor/deconstructor for `Annotated` instances. */
+ val Annotated: AnnotatedExtractor
+
+ /** An extractor class to create and pattern match with syntax `Annotated(annot, arg)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * arg @annot // for types
+ * arg: @annot // for exprs
+ */
+ abstract class AnnotatedExtractor {
+ def apply(annot: Tree, arg: Tree): Annotated
+ def unapply(annotated: Annotated): Option[(Tree, Tree)]
+ }
/** The API that all annotateds support */
trait AnnotatedApi extends TreeApi { this: Annotated =>
@@ -468,14 +1524,55 @@ trait Trees extends base.Trees { self: Universe =>
val arg: Tree
}
- override type SingletonTypeTree >: Null <: TypTree with SingletonTypeTreeApi
+ /** Singleton type, eliminated by RefCheck */
+ type SingletonTypeTree >: Null <: TypTree with SingletonTypeTreeApi
+
+ /** A tag that preserves the identity of the `SingletonTypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SingletonTypeTreeTag: ClassTag[SingletonTypeTree]
+
+ /** The constructor/deconstructor for `SingletonTypeTree` instances. */
+ val SingletonTypeTree: SingletonTypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `SingletonTypeTree(ref)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * ref.type
+ */
+ abstract class SingletonTypeTreeExtractor {
+ def apply(ref: Tree): SingletonTypeTree
+ def unapply(singletonTypeTree: SingletonTypeTree): Option[Tree]
+ }
/** The API that all singleton type trees support */
trait SingletonTypeTreeApi extends TypTreeApi { this: SingletonTypeTree =>
val ref: Tree
}
- override type SelectFromTypeTree >: Null <: TypTree with RefTree with SelectFromTypeTreeApi
+ /** Type selection <qualifier> # <name>, eliminated by RefCheck */
+ // [Eugene++] don't see why we need it, when we have Select
+ type SelectFromTypeTree >: Null <: TypTree with RefTree with SelectFromTypeTreeApi
+
+ /** A tag that preserves the identity of the `SelectFromTypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SelectFromTypeTreeTag: ClassTag[SelectFromTypeTree]
+
+ /** The constructor/deconstructor for `SelectFromTypeTree` instances. */
+ val SelectFromTypeTree: SelectFromTypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `SelectFromTypeTree(qualifier, name)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * qualifier # selector
+ *
+ * Note: a path-dependent type p.T is expressed as p.type # T
+ */
+ abstract class SelectFromTypeTreeExtractor {
+ def apply(qualifier: Tree, name: TypeName): SelectFromTypeTree
+ def unapply(selectFromTypeTree: SelectFromTypeTree): Option[(Tree, TypeName)]
+ }
/** The API that all selects from type trees support */
trait SelectFromTypeTreeApi extends TypTreeApi with RefTreeApi { this: SelectFromTypeTree =>
@@ -483,14 +1580,52 @@ trait Trees extends base.Trees { self: Universe =>
val name: TypeName
}
- override type CompoundTypeTree >: Null <: TypTree with CompoundTypeTreeApi
+ /** Intersection type <parent1> with ... with <parentN> { <decls> }, eliminated by RefCheck */
+ type CompoundTypeTree >: Null <: TypTree with CompoundTypeTreeApi
+
+ /** A tag that preserves the identity of the `CompoundTypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val CompoundTypeTreeTag: ClassTag[CompoundTypeTree]
+
+ /** The constructor/deconstructor for `CompoundTypeTree` instances. */
+ val CompoundTypeTree: CompoundTypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `CompoundTypeTree(templ)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * parent1 with ... with parentN { refinement }
+ */
+ abstract class CompoundTypeTreeExtractor {
+ def apply(templ: Template): CompoundTypeTree
+ def unapply(compoundTypeTree: CompoundTypeTree): Option[Template]
+ }
/** The API that all compound type trees support */
trait CompoundTypeTreeApi extends TypTreeApi { this: CompoundTypeTree =>
val templ: Template
}
- override type AppliedTypeTree >: Null <: TypTree with AppliedTypeTreeApi
+ /** Applied type <tpt> [ <args> ], eliminated by RefCheck */
+ type AppliedTypeTree >: Null <: TypTree with AppliedTypeTreeApi
+
+ /** A tag that preserves the identity of the `AppliedTypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AppliedTypeTreeTag: ClassTag[AppliedTypeTree]
+
+ /** The constructor/deconstructor for `AppliedTypeTree` instances. */
+ val AppliedTypeTree: AppliedTypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `AppliedTypeTree(tpt, args)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * tpt[args]
+ */
+ abstract class AppliedTypeTreeExtractor {
+ def apply(tpt: Tree, args: List[Tree]): AppliedTypeTree
+ def unapply(appliedTypeTree: AppliedTypeTree): Option[(Tree, List[Tree])]
+ }
/** The API that all applied type trees support */
trait AppliedTypeTreeApi extends TypTreeApi { this: AppliedTypeTree =>
@@ -498,7 +1633,26 @@ trait Trees extends base.Trees { self: Universe =>
val args: List[Tree]
}
- override type TypeBoundsTree >: Null <: TypTree with TypeBoundsTreeApi
+ /** Document me! */
+ type TypeBoundsTree >: Null <: TypTree with TypeBoundsTreeApi
+
+ /** A tag that preserves the identity of the `TypeBoundsTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeBoundsTreeTag: ClassTag[TypeBoundsTree]
+
+ /** The constructor/deconstructor for `TypeBoundsTree` instances. */
+ val TypeBoundsTree: TypeBoundsTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeBoundsTree(lo, hi)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * >: lo <: hi
+ */
+ abstract class TypeBoundsTreeExtractor {
+ def apply(lo: Tree, hi: Tree): TypeBoundsTree
+ def unapply(typeBoundsTree: TypeBoundsTree): Option[(Tree, Tree)]
+ }
/** The API that all type bound trees support */
trait TypeBoundsTreeApi extends TypTreeApi { this: TypeBoundsTree =>
@@ -506,7 +1660,26 @@ trait Trees extends base.Trees { self: Universe =>
val hi: Tree
}
- override type ExistentialTypeTree >: Null <: TypTree with ExistentialTypeTreeApi
+ /** Document me! */
+ type ExistentialTypeTree >: Null <: TypTree with ExistentialTypeTreeApi
+
+ /** A tag that preserves the identity of the `ExistentialTypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ExistentialTypeTreeTag: ClassTag[ExistentialTypeTree]
+
+ /** The constructor/deconstructor for `ExistentialTypeTree` instances. */
+ val ExistentialTypeTree: ExistentialTypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `ExistentialTypeTree(tpt, whereClauses)`.
+ * This AST node corresponds to the following Scala code:
+ *
+ * tpt forSome { whereClauses }
+ */
+ abstract class ExistentialTypeTreeExtractor {
+ def apply(tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree
+ def unapply(existentialTypeTree: ExistentialTypeTree): Option[(Tree, List[Tree])]
+ }
/** The API that all existential type trees support */
trait ExistentialTypeTreeApi extends TypTreeApi { this: ExistentialTypeTree =>
@@ -514,7 +1687,29 @@ trait Trees extends base.Trees { self: Universe =>
val whereClauses: List[Tree]
}
- override type TypeTree >: Null <: TypTree with TypeTreeApi
+ /** A synthetic tree holding an arbitrary type. Not to be confused with
+ * with TypTree, the trait for trees that are only used for type trees.
+ * TypeTree's are inserted in several places, but most notably in
+ * `RefCheck`, where the arbitrary type trees are all replaced by
+ * TypeTree's. */
+ type TypeTree >: Null <: TypTree with TypeTreeApi
+
+ /** A tag that preserves the identity of the `TypeTree` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeTreeTag: ClassTag[TypeTree]
+
+ /** The constructor/deconstructor for `TypeTree` instances. */
+ val TypeTree: TypeTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeTree()`.
+ * This AST node does not have direct correspondence to Scala code,
+ * and is emitted by everywhere when we want to wrap a `Type` in a `Tree`.
+ */
+ abstract class TypeTreeExtractor {
+ def apply(): TypeTree
+ def unapply(typeTree: TypeTree): Boolean
+ }
/** The API that all type trees support */
trait TypeTreeApi extends TypTreeApi { this: TypeTree =>
@@ -528,6 +1723,83 @@ trait Trees extends base.Trees { self: Universe =>
*/
val emptyValDef: ValDef
+// ---------------------- factories ----------------------------------------------
+
+ /** @param sym the class symbol
+ * @param impl the implementation template
+ */
+ def ClassDef(sym: Symbol, impl: Template): ClassDef
+
+ /**
+ * @param sym the class symbol
+ * @param impl the implementation template
+ */
+ def ModuleDef(sym: Symbol, impl: Template): ModuleDef
+
+ def ValDef(sym: Symbol, rhs: Tree): ValDef
+
+ def ValDef(sym: Symbol): ValDef
+
+ def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, rhs: Tree): DefDef
+
+ def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef
+
+ /** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */
+ def TypeDef(sym: Symbol, rhs: Tree): TypeDef
+
+ /** A TypeDef node which defines abstract type or type parameter for given `sym` */
+ def TypeDef(sym: Symbol): TypeDef
+
+ def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef
+
+ /** Block factory that flattens directly nested blocks.
+ */
+ def Block(stats: Tree*): Block
+
+ /** casedef shorthand */
+ def CaseDef(pat: Tree, body: Tree): CaseDef
+
+ def Bind(sym: Symbol, body: Tree): Bind
+
+ def Try(body: Tree, cases: (Tree, Tree)*): Try
+
+ def Throw(tpe: Type, args: Tree*): Throw
+
+ /** Factory method for object creation `new tpt(args_1)...(args_n)`
+ * A `New(t, as)` is expanded to: `(new t).<init>(as)`
+ */
+ def New(tpt: Tree, argss: List[List[Tree]]): Tree
+
+ /** 0-1 argument list new, based on a type.
+ */
+ def New(tpe: Type, args: Tree*): Tree
+
+ def New(sym: Symbol, args: Tree*): Tree
+
+ def Apply(sym: Symbol, args: Tree*): Tree
+
+ def ApplyConstructor(tpt: Tree, args: List[Tree]): Tree
+
+ def Super(sym: Symbol, mix: TypeName): Tree
+
+ def This(sym: Symbol): Tree
+
+ def Select(qualifier: Tree, name: String): Select
+
+ def Select(qualifier: Tree, sym: Symbol): Select
+
+ def Ident(name: String): Ident
+
+ def Ident(sym: Symbol): Ident
+
+ def TypeTree(tp: Type): TypeTree
+
// ---------------------- copying ------------------------------------------------
/** The standard (lazy) tree copier
@@ -673,9 +1945,35 @@ trait Trees extends base.Trees { self: Universe =>
protected def xtransform(transformer: Transformer, tree: Tree): Tree = throw new MatchError(tree)
- type Modifiers >: Null <: ModifiersApi
- abstract class ModifiersApi extends ModifiersBase
+ /** ... */
+ type Modifiers >: Null <: AnyRef with ModifiersApi
-}
+ /** A tag that preserves the identity of the `Modifiers` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ModifiersTag: ClassTag[Modifiers]
+
+ /** ... */
+ abstract class ModifiersApi {
+ def flags: FlagSet // default: NoFlags
+ def hasFlag(flag: FlagSet): Boolean
+ def privateWithin: Name // default: EmptyTypeName
+ def annotations: List[Tree] // default: List()
+ def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers =
+ Modifiers(flags, privateWithin, f(annotations))
+ }
+
+ val Modifiers: ModifiersCreator
+ abstract class ModifiersCreator {
+ def apply(): Modifiers = Modifiers(NoFlags, EmptyTypeName, List())
+ def apply(flags: FlagSet, privateWithin: Name, annotations: List[Tree]): Modifiers
+ }
+
+ def Modifiers(flags: FlagSet, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List())
+ def Modifiers(flags: FlagSet): Modifiers = Modifiers(flags, EmptyTypeName)
+
+ /** ... */
+ lazy val NoMods = Modifiers()
+}
diff --git a/src/reflect/scala/reflect/api/TypeCreator.scala b/src/reflect/scala/reflect/api/TypeCreator.scala
new file mode 100644
index 0000000000..cc6d38c548
--- /dev/null
+++ b/src/reflect/scala/reflect/api/TypeCreator.scala
@@ -0,0 +1,26 @@
+package scala.reflect
+package api
+
+/** A mirror-aware factory for types.
+ *
+ * In the reflection API, artifacts are specific to universes and
+ * symbolic references used in artifacts (e.g. `scala.Int`) are resolved by mirrors.
+ *
+ * Therefore to build a type one needs to know a universe that the type is going to be bound to
+ * and a mirror that is going to resolve symbolic references (e.g. to determine that `scala.Int`
+ * points to a core class `Int` from scala-library.jar).
+ *
+ * `TypeCreator` implements this notion by providing a standalone type factory.
+ *
+ * This is immediately useful for type tags. When the compiler creates a type tag,
+ * the end result needs to make sense in any mirror. That's because the compiler knows
+ * the universe it's creating a type tag for (since `TypeTag` is path-dependent on a universe),
+ * but it cannot know in advance the mirror to instantiate the result in (e.g. on JVM
+ * it doesn't know what classloader use to resolve symbolic names in the type tag).
+ *
+ * Due to a typechecker restriction (no eta-expansion for dependent method types),
+ * `TypeCreator` can't have a functional type, so it's implemented as class with an apply method.
+ */
+abstract class TypeCreator {
+ def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type
+}
diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala
new file mode 100644
index 0000000000..a7e58d2bcb
--- /dev/null
+++ b/src/reflect/scala/reflect/api/TypeTags.scala
@@ -0,0 +1,354 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2012 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+package scala
+package reflect
+package api
+
+import java.lang.{ Class => jClass }
+import scala.language.implicitConversions
+
+/*
+ * TODO
+ * add @see to docs about universes
+ * [Eugene++] also mention sensitivity to prefixes, i.e. that rb.TypeTag is different from ru.TypeTag
+ * [Chris++] tag.in(some mirror) or expr.in(some mirror) (does not work for tag and exprs in macros)
+ * Backwards compat item1: [Eugene++] it might be useful, though, to guard against abstractness of the incoming type.
+ */
+/**
+ * A type tag encapsulates a representation of type T.
+ *
+ * Type tags replace the pre-2.10 concept of a [[scala.reflect.Manifest]] and are integrated with reflection.
+ *
+ * === Overview and examples ===
+ *
+ * Type tags are organized in a hierarchy of three classes:
+ * [[scala.reflect.ClassTag]], [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#WeakTypeTag]].
+ *
+ * @see [[scala.reflect.ClassTag]], [[scala.reflect.api.Universe#TypeTag]], [[scala.reflect.api.Universe#WeakTypeTag]]
+ *
+ * Examples:
+ * {{{
+ * scala> class Person
+ * scala> class Container[T]
+ * scala> import scala.reflect.ClassTag
+ * scala> import scala.reflect.runtime.universe.TypeTag
+ * scala> import scala.reflect.runtime.universe.WeakTypeTag
+ * scala> def firstTypeArg( tag: WeakTypeTag[_] ) = (tag.tpe match {case TypeRef(_,_,typeArgs) => typeArgs})(0)
+ * }}}
+ * TypeTag contains concrete type arguments:
+ * {{{
+ * scala> firstTypeArg( implicitly[TypeTag[Container[Person]]] )
+ * res0: reflect.runtime.universe.Type = Person
+ * }}}
+ * TypeTag guarantees concrete type arguments (fails for references to unbound type arguments):
+ * {{{
+ * scala> def foo1[T] = implicitly[TypeTag[Container[T]]]
+ * <console>:11: error: No TypeTag available for Container[T]
+ * def foo1[T] = implicitly[TypeTag[Container[T]]]
+ * }}}
+ * WeakTypeTag allows references to unbound type arguments:
+ * {{{
+ * scala> def foo2[T] = firstTypeArg( implicitly[WeakTypeTag[Container[T]]] )
+ * foo2: [T]=> reflect.runtime.universe.Type
+ * scala> foo2[Person]
+ * res1: reflect.runtime.universe.Type = T
+ * }}}
+ * TypeTag allows unbound type arguments for which type tags are available:
+ * {{{
+ * scala> def foo3[T:TypeTag] = firstTypeArg( implicitly[TypeTag[Container[T]]] )
+ * foo3: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.Type
+ * scala> foo3[Person]
+ * res1: reflect.runtime.universe.Type = Person
+ * }}}
+ * WeakTypeTag contains concrete type arguments if available via existing tags:
+ * {{{
+ * scala> def foo4[T:WeakTypeTag] = firstTypeArg( implicitly[WeakTypeTag[Container[T]]] )
+ * foo4: [T](implicit evidence$1: reflect.runtime.universe.WeakTypeTag[T])reflect.runtime.universe.Type
+ * scala> foo4[Person]
+ * res1: reflect.runtime.universe.Type = Person
+ * }}}
+ *
+ *
+ * [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#WeakTypeTag]] are path dependent on their universe.
+ *
+ * The default universe is [[scala.reflect.runtime.universe]]
+ *
+ * Type tags can be migrated to another universe given the corresponding mirror using
+ *
+ * {{{
+ * tag.in( other_mirror )
+ * }}}
+ *
+ * See [[scala.reflect.api.TypeTags#WeakTypeTag.in]]
+ *
+ * === WeakTypeTag vs TypeTag ===
+ *
+ * Be careful with WeakTypeTag, because it will reify types even if these types are abstract.
+ * This makes it easy to forget to tag one of the methods in the call chain and discover it much later in the runtime
+ * by getting cryptic errors far away from their source. For example, consider the following snippet:
+ *
+ * {{{
+ * def bind[T: WeakTypeTag](name: String, value: T): IR.Result = bind((name, value))
+ * def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value)
+ * object NamedParam {
+ * implicit def namedValue[T: WeakTypeTag](name: String, x: T): NamedParam = apply(name, x)
+ * def apply[T: WeakTypeTag](name: String, x: T): NamedParam = new Typed[T](name, x)
+ * }
+ * }}}
+ *
+ * This fragment of the Scala REPL implementation defines a `bind` function that carries a named value along with its type
+ * into the heart of the REPL. Using a [[scala.reflect.api.Universe#WeakTypeTag]] here is reasonable, because it is desirable
+ * to work with all types, even if they are type parameters or abstract type members.
+ *
+ * However if any of the three `WeakTypeTag` context bounds is omitted, the resulting code will be incorrect,
+ * because the missing `WeakTypeTag` will be transparently generated by the compiler, carrying meaningless information.
+ * Most likely, this problem will manifest itself elsewhere, making debugging complicated.
+ * If `WeakTypeTag` context bounds were replaced with `TypeTag`, then such errors would be reported statically.
+ * But in that case we wouldn't be able to use `bind` in arbitrary contexts.
+ *
+ * === Backward compatibility with Manifests ===
+ *
+ * Type tags correspond loosely to manifests.
+ *
+ * More precisely:
+ * The previous notion of a [[scala.reflect.ClassManifest]] corresponds to a scala.reflect.ClassTag,
+ * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.runtime.universe.TypeTag,
+ *
+ * In Scala 2.10, manifests are deprecated, so it's advisable to migrate them to tags,
+ * because manifests will probably be removed in the next major release.
+ *
+ * In most cases it will be enough to replace ClassManifest with ClassTag and Manifest with TypeTag.
+ * There are however a few caveats:
+ *
+ * 1) The notion of OptManifest is no longer supported. Tags can reify arbitrary types, so they are always available.
+ *
+ * 2) There's no equivalent for AnyValManifest. Consider comparing your tag with one of the base tags
+ * (defined in the corresponding companion objects) to find out whether it represents a primitive value class.
+ * You can also use `<tag>.tpe.typeSymbol.isPrimitiveValueClass` for that purpose (requires scala-reflect.jar).
+ *
+ * 3) There's no replacement for factory methods defined in `ClassManifest` and `Manifest` companion objects.
+ * Consider assembling corresponding types using the reflection APIs provided by Java (for classes) and Scala (for types).
+ *
+ * 4) Certain manifest functions (such as `<:<`, `>:>` and `typeArguments`) weren't included in the tag API.
+ * Consider using the reflection APIs provided by Java (for classes) and Scala (for types) instead.
+ */
+trait TypeTags { self: Universe =>
+
+ import definitions._
+
+ /**
+ * If an implicit value of type WeakTypeTag[T] is required, the compiler will create one.
+ * A reflective representation of T can be accessed via the tpe field.
+ * Components of T can be references to type parameters or abstract types. WeakTypeTag makes an effort to
+ * be as concrete as possible, i.e. if type tags are available for the referenced type arguments or abstract types,
+ * they are used to embed the concrete types into the WeakTypeTag. Otherwise the WeakTypeTag will contain a reference
+ * to an abstract type. This behavior can be useful, when one expects T to be possibly partially abstract, but
+ * requires special care to handle this case. If however T is expected to be fully known, use
+ * [[scala.reflect.api.Universe#TypeTag]] instead, which statically guarantees this property.
+ *
+ * @see [[scala.reflect.api.TypeTags]]
+ */
+ @annotation.implicitNotFound(msg = "No WeakTypeTag available for ${T}")
+ trait WeakTypeTag[T] extends Equals with Serializable {
+ /**
+ * Mirror corresponding to the universe of this WeakTypeTag.
+ */
+ val mirror: Mirror
+ /**
+ * Migrates type tag to another universe.
+ *
+ * Type tags are path dependent on their universe. This methods allows migration
+ * given the mirror corresponding to the target universe.
+ *
+ * Migration means that all symbolic references to classes/objects/packages in the expression
+ * will be re-resolved within the new mirror (typically using that mirror's classloader).
+ */
+ def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # WeakTypeTag[T]
+
+ /**
+ * Reflective representation of type T.
+ */
+ def tpe: Type
+
+ // case class accessories
+ override def canEqual(x: Any) = x.isInstanceOf[WeakTypeTag[_]]
+ override def equals(x: Any) = x.isInstanceOf[WeakTypeTag[_]] && this.mirror == x.asInstanceOf[WeakTypeTag[_]].mirror && this.tpe == x.asInstanceOf[WeakTypeTag[_]].tpe
+ override def hashCode = mirror.hashCode * 31 + tpe.hashCode
+ override def toString = "WeakTypeTag[" + tpe + "]"
+ }
+
+ /**
+ * Type tags corresponding to primitive types and constructor/extractor for WeakTypeTags.
+ */
+ object WeakTypeTag {
+ val Byte : WeakTypeTag[scala.Byte] = TypeTag.Byte
+ val Short : WeakTypeTag[scala.Short] = TypeTag.Short
+ val Char : WeakTypeTag[scala.Char] = TypeTag.Char
+ val Int : WeakTypeTag[scala.Int] = TypeTag.Int
+ val Long : WeakTypeTag[scala.Long] = TypeTag.Long
+ val Float : WeakTypeTag[scala.Float] = TypeTag.Float
+ val Double : WeakTypeTag[scala.Double] = TypeTag.Double
+ val Boolean : WeakTypeTag[scala.Boolean] = TypeTag.Boolean
+ val Unit : WeakTypeTag[scala.Unit] = TypeTag.Unit
+ val Any : WeakTypeTag[scala.Any] = TypeTag.Any
+ val AnyVal : WeakTypeTag[scala.AnyVal] = TypeTag.AnyVal
+ val AnyRef : WeakTypeTag[scala.AnyRef] = TypeTag.AnyRef
+ val Object : WeakTypeTag[java.lang.Object] = TypeTag.Object
+ val Nothing : WeakTypeTag[scala.Nothing] = TypeTag.Nothing
+ val Null : WeakTypeTag[scala.Null] = TypeTag.Null
+
+
+ def apply[T](mirror1: MirrorOf[self.type], tpec1: TypeCreator): WeakTypeTag[T] =
+ tpec1(mirror1) match {
+ case ByteTpe => WeakTypeTag.Byte.asInstanceOf[WeakTypeTag[T]]
+ case ShortTpe => WeakTypeTag.Short.asInstanceOf[WeakTypeTag[T]]
+ case CharTpe => WeakTypeTag.Char.asInstanceOf[WeakTypeTag[T]]
+ case IntTpe => WeakTypeTag.Int.asInstanceOf[WeakTypeTag[T]]
+ case LongTpe => WeakTypeTag.Long.asInstanceOf[WeakTypeTag[T]]
+ case FloatTpe => WeakTypeTag.Float.asInstanceOf[WeakTypeTag[T]]
+ case DoubleTpe => WeakTypeTag.Double.asInstanceOf[WeakTypeTag[T]]
+ case BooleanTpe => WeakTypeTag.Boolean.asInstanceOf[WeakTypeTag[T]]
+ case UnitTpe => WeakTypeTag.Unit.asInstanceOf[WeakTypeTag[T]]
+ case AnyTpe => WeakTypeTag.Any.asInstanceOf[WeakTypeTag[T]]
+ case AnyValTpe => WeakTypeTag.AnyVal.asInstanceOf[WeakTypeTag[T]]
+ case AnyRefTpe => WeakTypeTag.AnyRef.asInstanceOf[WeakTypeTag[T]]
+ case ObjectTpe => WeakTypeTag.Object.asInstanceOf[WeakTypeTag[T]]
+ case NothingTpe => WeakTypeTag.Nothing.asInstanceOf[WeakTypeTag[T]]
+ case NullTpe => WeakTypeTag.Null.asInstanceOf[WeakTypeTag[T]]
+ case _ => new WeakTypeTagImpl[T](mirror1.asInstanceOf[Mirror], tpec1)
+ }
+
+ def unapply[T](ttag: WeakTypeTag[T]): Option[Type] = Some(ttag.tpe)
+ }
+
+ private class WeakTypeTagImpl[T](val mirror: Mirror, val tpec: TypeCreator) extends WeakTypeTag[T] {
+ lazy val tpe: Type = tpec(mirror)
+ def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # WeakTypeTag[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ otherMirror.universe.WeakTypeTag[T](otherMirror1, tpec)
+ }
+ private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = false)
+ }
+
+ /**
+ * A `TypeTag` is a [[scala.reflect.api.Universe#WeakTypeTag]] with the additional
+ * static guarantee that all type references are concrete, i.e. it does <b>not</b> contain any references to
+ * unresolved type parameters or abstract types.
+ *
+ * @see [[scala.reflect.api.TypeTags]]
+ */
+ @annotation.implicitNotFound(msg = "No TypeTag available for ${T}")
+ trait TypeTag[T] extends WeakTypeTag[T] with Equals with Serializable {
+ /**
+ * @inheritdoc
+ */
+ override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T]
+
+ // case class accessories
+ override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]]
+ override def equals(x: Any) = x.isInstanceOf[TypeTag[_]] && this.mirror == x.asInstanceOf[TypeTag[_]].mirror && this.tpe == x.asInstanceOf[TypeTag[_]].tpe
+ override def hashCode = mirror.hashCode * 31 + tpe.hashCode
+ override def toString = "TypeTag[" + tpe + "]"
+ }
+
+ object TypeTag {
+ val Byte: TypeTag[scala.Byte] = new PredefTypeTag[scala.Byte] (ByteTpe, _.TypeTag.Byte)
+ val Short: TypeTag[scala.Short] = new PredefTypeTag[scala.Short] (ShortTpe, _.TypeTag.Short)
+ val Char: TypeTag[scala.Char] = new PredefTypeTag[scala.Char] (CharTpe, _.TypeTag.Char)
+ val Int: TypeTag[scala.Int] = new PredefTypeTag[scala.Int] (IntTpe, _.TypeTag.Int)
+ val Long: TypeTag[scala.Long] = new PredefTypeTag[scala.Long] (LongTpe, _.TypeTag.Long)
+ val Float: TypeTag[scala.Float] = new PredefTypeTag[scala.Float] (FloatTpe, _.TypeTag.Float)
+ val Double: TypeTag[scala.Double] = new PredefTypeTag[scala.Double] (DoubleTpe, _.TypeTag.Double)
+ val Boolean: TypeTag[scala.Boolean] = new PredefTypeTag[scala.Boolean] (BooleanTpe, _.TypeTag.Boolean)
+ val Unit: TypeTag[scala.Unit] = new PredefTypeTag[scala.Unit] (UnitTpe, _.TypeTag.Unit)
+ val Any: TypeTag[scala.Any] = new PredefTypeTag[scala.Any] (AnyTpe, _.TypeTag.Any)
+ val AnyVal: TypeTag[scala.AnyVal] = new PredefTypeTag[scala.AnyVal] (AnyValTpe, _.TypeTag.AnyVal)
+ val AnyRef: TypeTag[scala.AnyRef] = new PredefTypeTag[scala.AnyRef] (AnyRefTpe, _.TypeTag.AnyRef)
+ val Object: TypeTag[java.lang.Object] = new PredefTypeTag[java.lang.Object] (ObjectTpe, _.TypeTag.Object)
+ val Nothing: TypeTag[scala.Nothing] = new PredefTypeTag[scala.Nothing] (NothingTpe, _.TypeTag.Nothing)
+ val Null: TypeTag[scala.Null] = new PredefTypeTag[scala.Null] (NullTpe, _.TypeTag.Null)
+
+ def apply[T](mirror1: MirrorOf[self.type], tpec1: TypeCreator): TypeTag[T] =
+ tpec1(mirror1) match {
+ case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]]
+ case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]]
+ case CharTpe => TypeTag.Char.asInstanceOf[TypeTag[T]]
+ case IntTpe => TypeTag.Int.asInstanceOf[TypeTag[T]]
+ case LongTpe => TypeTag.Long.asInstanceOf[TypeTag[T]]
+ case FloatTpe => TypeTag.Float.asInstanceOf[TypeTag[T]]
+ case DoubleTpe => TypeTag.Double.asInstanceOf[TypeTag[T]]
+ case BooleanTpe => TypeTag.Boolean.asInstanceOf[TypeTag[T]]
+ case UnitTpe => TypeTag.Unit.asInstanceOf[TypeTag[T]]
+ case AnyTpe => TypeTag.Any.asInstanceOf[TypeTag[T]]
+ case AnyValTpe => TypeTag.AnyVal.asInstanceOf[TypeTag[T]]
+ case AnyRefTpe => TypeTag.AnyRef.asInstanceOf[TypeTag[T]]
+ case ObjectTpe => TypeTag.Object.asInstanceOf[TypeTag[T]]
+ case NothingTpe => TypeTag.Nothing.asInstanceOf[TypeTag[T]]
+ case NullTpe => TypeTag.Null.asInstanceOf[TypeTag[T]]
+ case _ => new TypeTagImpl[T](mirror1.asInstanceOf[Mirror], tpec1)
+ }
+
+ def unapply[T](ttag: TypeTag[T]): Option[Type] = Some(ttag.tpe)
+ }
+
+ private class TypeTagImpl[T](mirror: Mirror, tpec: TypeCreator) extends WeakTypeTagImpl[T](mirror, tpec) with TypeTag[T] {
+ override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ otherMirror.universe.TypeTag[T](otherMirror1, tpec)
+ }
+ private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = true)
+ }
+
+ private class PredefTypeCreator[T](copyIn: Universe => Universe#TypeTag[T]) extends TypeCreator {
+ def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type = {
+ copyIn(m.universe).asInstanceOf[U # TypeTag[T]].tpe
+ }
+ }
+
+ private class PredefTypeTag[T](_tpe: Type, copyIn: Universe => Universe#TypeTag[T]) extends TypeTagImpl[T](rootMirror, new PredefTypeCreator(copyIn)) {
+ override lazy val tpe: Type = _tpe
+ private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = true)
+ }
+
+ /**
+ * Shortcut for `implicitly[WeakTypeTag[T]]`
+ */
+ def weakTypeTag[T](implicit attag: WeakTypeTag[T]) = attag
+
+ /**
+ * Shortcut for `implicitly[TypeTag[T]]`
+ */
+ def typeTag[T](implicit ttag: TypeTag[T]) = ttag
+
+ // big thanks to Viktor Klang for this brilliant idea!
+ /**
+ * Shortcut for `implicitly[WeakTypeTag[T]].tpe`
+ */
+ def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe
+
+ /**
+ * Shortcut for `implicitly[TypeTag[T]].tpe`
+ */
+ def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe
+}
+
+private[scala] class SerializedTypeTag(var tpec: TypeCreator, var concrete: Boolean) extends Serializable {
+ private def writeObject(out: java.io.ObjectOutputStream): Unit = {
+ out.writeObject(tpec)
+ out.writeBoolean(concrete)
+ }
+
+ private def readObject(in: java.io.ObjectInputStream): Unit = {
+ tpec = in.readObject().asInstanceOf[TypeCreator]
+ concrete = in.readBoolean()
+ }
+
+ private def readResolve(): AnyRef = {
+ import scala.reflect.runtime.universe._
+ if (concrete) TypeTag(rootMirror, tpec)
+ else WeakTypeTag(rootMirror, tpec)
+ }
+}
diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala
index 1c79de02c3..af70c9e761 100644
--- a/src/reflect/scala/reflect/api/Types.scala
+++ b/src/reflect/scala/reflect/api/Types.scala
@@ -1,13 +1,39 @@
package scala.reflect
package api
-trait Types extends base.Types { self: Universe =>
+/**
+ * Defines the type hierachy for types.
+ *
+ * Note: Because of implementation details, some type factories have return type `Type`
+ * instead of a more precise type.
+ *
+ * @see [[scala.reflect]] for a description on how the class hierarchy is encoded here.
+ */
+trait Types { self: Universe =>
+
+ /** The type of Scala types, and also Scala type signatures.
+ * (No difference is internally made between the two).
+ */
+ type Type >: Null <: TypeApi
- override type Type >: Null <: TypeApi
+ /** A tag that preserves the identity of the `Type` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeTagg: ClassTag[Type]
- /** The extended API of types
+ /** This constant is used as a special value that indicates that no meaningful type exists.
*/
- abstract class TypeApi extends TypeBase {
+ val NoType: Type
+
+ /** This constant is used as a special value denoting the empty prefix in a path dependent type.
+ * For instance `x.type` is represented as `SingleType(NoPrefix, <x>)`, where `<x>` stands for
+ * the symbol for `x`.
+ */
+ val NoPrefix: Type
+
+ /** The API of types
+ */
+ abstract class TypeApi {
/** The term symbol associated with the type, or `NoSymbol` for types
* that do not refer to a term symbol.
*/
@@ -152,42 +178,177 @@ trait Types extends base.Types { self: Universe =>
def contains(sym: Symbol): Boolean
}
- /** .. */
- override type ThisType >: Null <: SingletonType with ThisTypeApi
+ /** The type of Scala singleton types, i.e., types that are inhabited
+ * by only one nun-null value. These include types of the forms
+ * {{{
+ * C.this.type
+ * C.super.type
+ * x.type
+ * }}}
+ * as well as [[ConstantType constant types]].
+ */
+ type SingletonType >: Null <: Type
+
+ /** A tag that preserves the identity of the `SingletonType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SingletonTypeTag: ClassTag[SingletonType]
+
+ /** A singleton type that describes types of the form on the left with the
+ * corresponding `ThisType` representation to the right:
+ * {{{
+ * C.this.type ThisType(C)
+ * }}}
+ */
+ type ThisType >: Null <: AnyRef with SingletonType with ThisTypeApi
+
+ /** A tag that preserves the identity of the `ThisType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ThisTypeTag: ClassTag[ThisType]
+
+ /** The constructor/deconstructor for `ThisType` instances. */
+ val ThisType: ThisTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `ThisType(sym)`
+ * where `sym` is the class prefix of the this type.
+ */
+ abstract class ThisTypeExtractor {
+ /**
+ * Creates a ThisType from the given class symbol.
+ */
+ def apply(sym: Symbol): Type
+ def unapply(tpe: ThisType): Option[Symbol]
+ }
/** The API that all this types support */
trait ThisTypeApi extends TypeApi { this: ThisType =>
val sym: Symbol
}
- /** .. */
- override type SingleType >: Null <: SingletonType with SingleTypeApi
+ /** The `SingleType` type describes types of any of the forms on the left,
+ * with their TypeRef representations to the right.
+ * {{{
+ * (T # x).type SingleType(T, x)
+ * p.x.type SingleType(p.type, x)
+ * x.type SingleType(NoPrefix, x)
+ * }}}
+ */
+ type SingleType >: Null <: AnyRef with SingletonType with SingleTypeApi
+
+ /** A tag that preserves the identity of the `SingleType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SingleTypeTag: ClassTag[SingleType]
+
+ /** The constructor/deconstructor for `SingleType` instances. */
+ val SingleType: SingleTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `SingleType(pre, sym)`
+ * Here, `pre` is the prefix of the single-type, and `sym` is the stable value symbol
+ * referred to by the single-type.
+ */
+ abstract class SingleTypeExtractor {
+ def apply(pre: Type, sym: Symbol): Type // not SingleTypebecause of implementation details
+ def unapply(tpe: SingleType): Option[(Type, Symbol)]
+ }
/** The API that all single types support */
trait SingleTypeApi extends TypeApi { this: SingleType =>
val pre: Type
val sym: Symbol
}
+ /** The `SuperType` type is not directly written, but arises when `C.super` is used
+ * as a prefix in a `TypeRef` or `SingleType`. It's internal presentation is
+ * {{{
+ * SuperType(thistpe, supertpe)
+ * }}}
+ * Here, `thistpe` is the type of the corresponding this-type. For instance,
+ * in the type arising from C.super, the `thistpe` part would be `ThisType(C)`.
+ * `supertpe` is the type of the super class referred to by the `super`.
+ */
+ type SuperType >: Null <: AnyRef with SingletonType with SuperTypeApi
- /** .. */
- override type SuperType >: Null <: SingletonType with SuperTypeApi
+ /** A tag that preserves the identity of the `SuperType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val SuperTypeTag: ClassTag[SuperType]
+
+ /** The constructor/deconstructor for `SuperType` instances. */
+ val SuperType: SuperTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `SingleType(thistpe, supertpe)`
+ */
+ abstract class SuperTypeExtractor {
+ def apply(thistpe: Type, supertpe: Type): Type // not SuperTypebecause of implementation details
+ def unapply(tpe: SuperType): Option[(Type, Type)]
+ }
/** The API that all super types support */
trait SuperTypeApi extends TypeApi { this: SuperType =>
val thistpe: Type
val supertpe: Type
}
+ /** The `ConstantType` type is not directly written in user programs, but arises as the type of a constant.
+ * The REPL expresses constant types like `Int(11)`. Here are some constants with their types:
+ * {{{
+ * 1 ConstantType(Constant(1))
+ * "abc" ConstantType(Constant("abc"))
+ * }}}
+ */
+ type ConstantType >: Null <: AnyRef with SingletonType with ConstantTypeApi
+
+ /** A tag that preserves the identity of the `ConstantType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ConstantTypeTag: ClassTag[ConstantType]
- /** .. */
- override type ConstantType >: Null <: SingletonType with ConstantTypeApi
+ /** The constructor/deconstructor for `ConstantType` instances. */
+ val ConstantType: ConstantTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `ConstantType(constant)`
+ * Here, `constant` is the constant value represented by the type.
+ */
+ abstract class ConstantTypeExtractor {
+ def apply(value: Constant): ConstantType
+ def unapply(tpe: ConstantType): Option[Constant]
+ }
/** The API that all constant types support */
trait ConstantTypeApi extends TypeApi { this: ConstantType =>
val value: Constant
}
- /** .. */
- override type TypeRef >: Null <: Type with TypeRefApi
+ /** The `TypeRef` type describes types of any of the forms on the left,
+ * with their TypeRef representations to the right.
+ * {{{
+ * T # C[T_1, ..., T_n] TypeRef(T, C, List(T_1, ..., T_n))
+ * p.C[T_1, ..., T_n] TypeRef(p.type, C, List(T_1, ..., T_n))
+ * C[T_1, ..., T_n] TypeRef(NoPrefix, C, List(T_1, ..., T_n))
+ * T # C TypeRef(T, C, Nil)
+ * p.C TypeRef(p.type, C, Nil)
+ * C TypeRef(NoPrefix, C, Nil)
+ * }}}
+ */
+ type TypeRef >: Null <: AnyRef with Type with TypeRefApi
+
+ /** A tag that preserves the identity of the `TypeRef` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeRefTag: ClassTag[TypeRef]
+
+ /** The constructor/deconstructor for `TypeRef` instances. */
+ val TypeRef: TypeRefExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeRef(pre, sym, args)`
+ * Here, `pre` is the prefix of the type reference, `sym` is the symbol
+ * referred to by the type reference, and `args` is a possible empty list of
+ * type argumenrts.
+ */
+ abstract class TypeRefExtractor {
+ def apply(pre: Type, sym: Symbol, args: List[Type]): Type // not TypeRefbecause of implementation details
+ def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])]
+ }
/** The API that all type refs support */
trait TypeRefApi extends TypeApi { this: TypeRef =>
@@ -196,8 +357,46 @@ trait Types extends base.Types { self: Universe =>
val args: List[Type]
}
- /** .. */
- override type RefinedType >: Null <: CompoundType with RefinedTypeApi
+ /** A subtype of Type representing refined types as well as `ClassInfo` signatures.
+ */
+ type CompoundType >: Null <: AnyRef with Type
+
+ /** A tag that preserves the identity of the `CompoundType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val CompoundTypeTag: ClassTag[CompoundType]
+
+ /** The `RefinedType` type defines types of any of the forms on the left,
+ * with their RefinedType representations to the right.
+ * {{{
+ * P_1 with ... with P_m { D_1; ...; D_n} RefinedType(List(P_1, ..., P_m), Scope(D_1, ..., D_n))
+ * P_1 with ... with P_m RefinedType(List(P_1, ..., P_m), Scope())
+ * { D_1; ...; D_n} RefinedType(List(AnyRef), Scope(D_1, ..., D_n))
+ * }}}
+ */
+ type RefinedType >: Null <: AnyRef with CompoundType with RefinedTypeApi
+
+ /** A tag that preserves the identity of the `RefinedType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val RefinedTypeTag: ClassTag[RefinedType]
+
+ /** The constructor/deconstructor for `RefinedType` instances. */
+ val RefinedType: RefinedTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `RefinedType(parents, decls)`
+ * Here, `parents` is the list of parent types of the class, and `decls` is the scope
+ * containing all declarations in the class.
+ */
+ abstract class RefinedTypeExtractor {
+ def apply(parents: List[Type], decls: Scope): RefinedType
+
+ /** An alternative constructor that passes in the synthetic classs symbol
+ * that backs the refined type. (Normally, a fresh class symbol is created automatically).
+ */
+ def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType
+ def unapply(tpe: RefinedType): Option[(List[Type], Scope)]
+ }
/** The API that all refined types support */
trait RefinedTypeApi extends TypeApi { this: RefinedType =>
@@ -205,8 +404,35 @@ trait Types extends base.Types { self: Universe =>
val decls: Scope
}
- /** .. */
- override type ClassInfoType >: Null <: CompoundType with ClassInfoTypeApi
+ /** The `ClassInfo` type signature is used to define parents and declarations
+ * of classes, traits, and objects. If a class, trait, or object C is declared like this
+ * {{{
+ * C extends P_1 with ... with P_m { D_1; ...; D_n}
+ * }}}
+ * its `ClassInfo` type has the following form:
+ * {{{
+ * ClassInfo(List(P_1, ..., P_m), Scope(D_1, ..., D_n), C)
+ * }}}
+ */
+ type ClassInfoType >: Null <: AnyRef with CompoundType with ClassInfoTypeApi
+
+ /** A tag that preserves the identity of the `ClassInfoType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ClassInfoTypeTag: ClassTag[ClassInfoType]
+
+ /** The constructor/deconstructor for `ClassInfoType` instances. */
+ val ClassInfoType: ClassInfoTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `ClassInfo(parents, decls, clazz)`
+ * Here, `parents` is the list of parent types of the class, `decls` is the scope
+ * containing all declarations in the class, and `clazz` is the symbol of the class
+ * itself.
+ */
+ abstract class ClassInfoTypeExtractor {
+ def apply(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType
+ def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)]
+ }
/** The API that all class info types support */
trait ClassInfoTypeApi extends TypeApi { this: ClassInfoType =>
@@ -215,8 +441,36 @@ trait Types extends base.Types { self: Universe =>
val typeSymbol: Symbol
}
- /** .. */
- override type MethodType >: Null <: Type with MethodTypeApi
+ /** The `MethodType` type signature is used to indicate parameters and result type of a method
+ */
+ type MethodType >: Null <: AnyRef with Type with MethodTypeApi
+
+ /** A tag that preserves the identity of the `MethodType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val MethodTypeTag: ClassTag[MethodType]
+
+ /** The constructor/deconstructor for `MethodType` instances. */
+ val MethodType: MethodTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `MethodType(params, respte)`
+ * Here, `params` is a potentially empty list of parameter symbols of the method,
+ * and `restpe` is the result type of the method. If the method is curried, `restpe` would
+ * be another `MethodType`.
+ * Note: `MethodType(Nil, Int)` would be the type of a method defined with an empty parameter list.
+ * {{{
+ * def f(): Int
+ * }}}
+ * If the method is completely parameterless, as in
+ * {{{
+ * def f: Int
+ * }}}
+ * its type is a `NullaryMethodType`.
+ */
+ abstract class MethodTypeExtractor {
+ def apply(params: List[Symbol], resultType: Type): MethodType
+ def unapply(tpe: MethodType): Option[(List[Symbol], Type)]
+ }
/** The API that all method types support */
trait MethodTypeApi extends TypeApi { this: MethodType =>
@@ -224,16 +478,53 @@ trait Types extends base.Types { self: Universe =>
val resultType: Type
}
- /** .. */
- override type NullaryMethodType >: Null <: Type with NullaryMethodTypeApi
+ /** The `NullaryMethodType` type signature is used for parameterless methods
+ * with declarations of the form `def foo: T`
+ */
+ type NullaryMethodType >: Null <: AnyRef with Type with NullaryMethodTypeApi
+
+ /** A tag that preserves the identity of the `NullaryMethodType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val NullaryMethodTypeTag: ClassTag[NullaryMethodType]
+
+ /** The constructor/deconstructor for `NullaryMethodType` instances. */
+ val NullaryMethodType: NullaryMethodTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `NullaryMethodType(resultType)`.
+ * Here, `resultType` is the result type of the parameterless method.
+ */
+ abstract class NullaryMethodTypeExtractor {
+ def apply(resultType: Type): NullaryMethodType
+ def unapply(tpe: NullaryMethodType): Option[(Type)]
+ }
/** The API that all nullary method types support */
trait NullaryMethodTypeApi extends TypeApi { this: NullaryMethodType =>
val resultType: Type
}
- /** .. */
- override type PolyType >: Null <: Type with PolyTypeApi
+ /** The `PolyType` type signature is used for polymorphic methods
+ * that have at least one type parameter.
+ */
+ type PolyType >: Null <: AnyRef with Type with PolyTypeApi
+
+ /** A tag that preserves the identity of the `PolyType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val PolyTypeTag: ClassTag[PolyType]
+
+ /** The constructor/deconstructor for `PolyType` instances. */
+ val PolyType: PolyTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `PolyType(typeParams, resultType)`.
+ * Here, `typeParams` are the type parameters of the method and `resultType`
+ * is the type signature following the type parameters.
+ */
+ abstract class PolyTypeExtractor {
+ def apply(typeParams: List[Symbol], resultType: Type): PolyType
+ def unapply(tpe: PolyType): Option[(List[Symbol], Type)]
+ }
/** The API that all polymorphic types support */
trait PolyTypeApi extends TypeApi { this: PolyType =>
@@ -241,8 +532,28 @@ trait Types extends base.Types { self: Universe =>
val resultType: Type
}
- /** .. */
- override type ExistentialType >: Null <: Type with ExistentialTypeApi
+ /** The `ExistentialType` type signature is used for existential types and
+ * wildcard types.
+ */
+ type ExistentialType >: Null <: AnyRef with Type with ExistentialTypeApi
+
+ /** A tag that preserves the identity of the `ExistentialType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val ExistentialTypeTag: ClassTag[ExistentialType]
+
+ /** The constructor/deconstructor for `ExistentialType` instances. */
+ val ExistentialType: ExistentialTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax
+ * `ExistentialType(quantified, underlying)`.
+ * Here, `quantified` are the type variables bound by the existential type and `underlying`
+ * is the type that's existentially quantified.
+ */
+ abstract class ExistentialTypeExtractor {
+ def apply(quantified: List[Symbol], underlying: Type): ExistentialType
+ def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)]
+ }
/** The API that all existential types support */
trait ExistentialTypeApi extends TypeApi { this: ExistentialType =>
@@ -250,8 +561,28 @@ trait Types extends base.Types { self: Universe =>
val underlying: Type
}
- /** .. */
- override type AnnotatedType >: Null <: Type with AnnotatedTypeApi
+ /** The `AnnotatedType` type signature is used for annotated types of the
+ * for `<type> @<annotation>`.
+ */
+ type AnnotatedType >: Null <: AnyRef with Type with AnnotatedTypeApi
+
+ /** A tag that preserves the identity of the `AnnotatedType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val AnnotatedTypeTag: ClassTag[AnnotatedType]
+
+ /** The constructor/deconstructor for `AnnotatedType` instances. */
+ val AnnotatedType: AnnotatedTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax
+ * `AnnotatedType(annotations, underlying, selfsym)`.
+ * Here, `annotations` are the annotations decorating the underlying type `underlying`.
+ * `selfSym` is a symbol representing the annotated type itself.
+ */
+ abstract class AnnotatedTypeExtractor {
+ def apply(annotations: List[Annotation], underlying: Type, selfsym: Symbol): AnnotatedType
+ def unapply(tpe: AnnotatedType): Option[(List[Annotation], Type, Symbol)]
+ }
/** The API that all annotated types support */
trait AnnotatedTypeApi extends TypeApi { this: AnnotatedType =>
@@ -260,8 +591,34 @@ trait Types extends base.Types { self: Universe =>
val selfsym: Symbol
}
- /** .. */
- override type TypeBounds >: Null <: Type with TypeBoundsApi
+ /** The `TypeBounds` type signature is used to indicate lower and upper type bounds
+ * of type parameters and abstract types. It is not a first-class type.
+ * If an abstract type or type parameter is declared with any of the forms
+ * on the left, its type signature is the TypeBounds type on the right.
+ * {{{
+ * T >: L <: U TypeBounds(L, U)
+ * T >: L TypeBounds(L, Any)
+ * T <: U TypeBounds(Nothing, U)
+ * }}}
+ */
+ type TypeBounds >: Null <: AnyRef with Type with TypeBoundsApi
+
+ /** A tag that preserves the identity of the `TypeBounds` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val TypeBoundsTag: ClassTag[TypeBounds]
+
+ /** The constructor/deconstructor for `TypeBounds` instances. */
+ val TypeBounds: TypeBoundsExtractor
+
+ /** An extractor class to create and pattern match with syntax `TypeBound(lower, upper)`
+ * Here, `lower` is the lower bound of the `TypeBounds` pair, and `upper` is
+ * the upper bound.
+ */
+ abstract class TypeBoundsExtractor {
+ def apply(lo: Type, hi: Type): TypeBounds
+ def unapply(tpe: TypeBounds): Option[(Type, Type)]
+ }
/** The API that all type bounds support */
trait TypeBoundsApi extends TypeApi { this: TypeBounds =>
@@ -269,8 +626,38 @@ trait Types extends base.Types { self: Universe =>
val hi: Type
}
- /** .. */
- override type BoundedWildcardType >: Null <: Type with BoundedWildcardTypeApi
+ /** An object representing an unknown type, used during type inference.
+ * If you see WildcardType outside of inference it is almost certainly a bug.
+ */
+ val WildcardType: Type
+
+ /** BoundedWildcardTypes, used only during type inference, are created in
+ * two places:
+ *
+ * 1. If the expected type of an expression is an existential type,
+ * its hidden symbols are replaced with bounded wildcards.
+ * 2. When an implicit conversion is being sought based in part on
+ * the name of a method in the converted type, a HasMethodMatching
+ * type is created: a MethodType with parameters typed as
+ * BoundedWildcardTypes.
+ */
+ type BoundedWildcardType >: Null <: AnyRef with Type with BoundedWildcardTypeApi
+
+ /** A tag that preserves the identity of the `BoundedWildcardType` abstract type from erasure.
+ * Can be used for pattern matching, instance tests, serialization and likes.
+ */
+ implicit val BoundedWildcardTypeTag: ClassTag[BoundedWildcardType]
+
+ /** The constructor/deconstructor for `BoundedWildcardType` instances. */
+ val BoundedWildcardType: BoundedWildcardTypeExtractor
+
+ /** An extractor class to create and pattern match with syntax `BoundedWildcardTypeExtractor(bounds)`
+ * with `bounds` denoting the type bounds.
+ */
+ abstract class BoundedWildcardTypeExtractor {
+ def apply(bounds: TypeBounds): BoundedWildcardType
+ def unapply(tpe: BoundedWildcardType): Option[TypeBounds]
+ }
/** The API that all this types support */
trait BoundedWildcardTypeApi extends TypeApi { this: BoundedWildcardType =>
diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala
index 3165f9abcd..7d0f6cf0d6 100644
--- a/src/reflect/scala/reflect/api/Universe.scala
+++ b/src/reflect/scala/reflect/api/Universe.scala
@@ -1,17 +1,82 @@
package scala.reflect
package api
-abstract class Universe extends base.Universe
- with Symbols
+abstract class Universe extends Symbols
with Types
with FlagSets
+ with Scopes
with Names
with Trees
- with Printers
with Constants
+ with Annotations
with Positions
- with Mirrors
+ with Exprs
+ with TypeTags
+ with TagInterop
with StandardDefinitions
with StandardNames
+ with BuildUtils
+ with Mirrors
+ with Printers
with Importers
- with Annotations
+{
+ /** Produce the abstract syntax tree representing the given Scala expression.
+ *
+ * For example
+ *
+ * {{{
+ * val five = reify{ 5 } // Literal(Constant(5))
+ * reify{ 2 + 4 } // Apply( Select( Literal(Constant(2)), newTermName("$plus")), List( Literal(Constant(4)) ) )
+ * reify{ five.splice + 4 } // Apply( Select( Literal(Constant(5)), newTermName("$plus")), List( Literal(Constant(4)) ) )
+ * }}}
+ *
+ * The produced tree is path dependent on the Universe `reify` was called from.
+ *
+ * Use [[scala.reflect.api.Exprs#Expr.splice]] to embed an existing expression into a reify call. Use [[Expr]] to turn a [[Tree]] into an expression that can be spliced.
+ *
+ * == Further info and implementation details ==
+ *
+ * `reify` is implemented as a macro, which given an expression, generates a tree that when compiled and executed produces the original tree.
+ *
+ * For instance in `reify{ x + 1 }` the macro `reify` receives the abstract syntax tree of `x + 1` as its argument, which is
+ *
+ * {{{
+ * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1))))
+ * }}}
+ *
+ * and returns a tree, which produces the tree above, when compiled and executed. So in other terms, the refiy call expands to something like
+ *
+ * {{{
+ * val $u: u.type = u // where u is a reference to the Universe that calls the reify
+ * $u.Expr[Int]($u.Apply($u.Select($u.Ident($u.newFreeVar("x", <Int>, x), "+"), List($u.Literal($u.Constant(1))))))
+ * }}}
+ *
+ * ------
+ *
+ * Reification performs expression splicing (when processing Expr.splice)
+ * and type splicing (for every type T that has a TypeTag[T] implicit in scope):
+ *
+ * {{{
+ * val two = mirror.reify(2) // Literal(Constant(2))
+ * val four = mirror.reify(two.splice + two.splice) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree))
+ *
+ * def macroImpl[T](c: Context) = {
+ * ...
+ * // T here is just a type parameter, so the tree produced by reify won't be of much use in a macro expansion
+ * // however, if T were annotated with c.WeakTypeTag (which would declare an implicit parameter for macroImpl)
+ * // then reification would substitute T with the TypeTree that was used in a TypeApply of this particular macro invocation
+ * val factory = c.reify{ new Queryable[T] }
+ * ...
+ * }
+ * }}}
+ *
+ * The transformation looks mostly straightforward, but it has its tricky parts:
+ * - Reifier retains symbols and types defined outside the reified tree, however
+ * locally defined entities get erased and replaced with their original trees
+ * - Free variables are detected and wrapped in symbols of the type `FreeTermSymbol` or `FreeTypeSymbol`
+ * - Mutable variables that are accessed from a local function are wrapped in refs
+ */
+ // implementation is hardwired to `scala.reflect.reify.Taggers`
+ // using the mechanism implemented in `scala.tools.reflect.FastTrack`
+ def reify[T](expr: T): Expr[T] = ??? // macro
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/api/package.scala b/src/reflect/scala/reflect/api/package.scala
index 5e31071e2d..0b2a43936e 100644
--- a/src/reflect/scala/reflect/api/package.scala
+++ b/src/reflect/scala/reflect/api/package.scala
@@ -1,15 +1,80 @@
package scala.reflect
-package object api {
-
- // type and value aliases for slices of the base Universe cake that are not
- // repeated in api.Universe
- type Scopes = base.Scopes
- type BuildUtils = base.BuildUtils
- type Attachments = base.Attachments
+import scala.reflect.api.{Universe => ApiUniverse}
- type MirrorOf[U <: base.Universe with Singleton] = base.MirrorOf[U]
+/**
+ * The main package of Scala's reflection library.
+ *
+ * The reflection library is structured according to the 'cake pattern'. The main layer
+ * resides in package [[scala.reflect.api]] and defines an interface to the following main types:
+ *
+ * - [[scala.reflect.api.Types#Type Types]] represent types
+ * - [[scala.reflect.api.Symbols#Symbol Symbols]] represent definitions
+ * - [[scala.reflect.api.Trees#Tree Trees]] represent abstract syntax trees
+ * - [[scala.reflect.api.Names#Name Names]] represent term and type names
+ * - [[scala.reflect.api.Annotations#Annotation Annotations]] represent annotations
+ * - [[scala.reflect.api.Positions#Position Positions]] represent source positions of tree nodes
+ * - [[scala.reflect.api.FlagSets#FlagSet FlagSet]] represent sets of flags that apply to symbols and
+ * definition trees
+ * - [[scala.reflect.api.Constants#Constant Constants]] represent compile-time constants.
+ *
+ * Each of these types are defined in their own enclosing traits, which are ultimately all inherited by class
+ * [[scala.reflect.api.Universe Universe]]. The main universe defines a minimal interface to the above types.
+ * Universes that provide additional functionality such as deeper introspection or runtime code generation,
+ * are defined in packages [[scala.reflect.api]] and `scala.tools.reflect`.
+ *
+ * The cake pattern employed here requires to write certain Scala idioms with more indirections that usual.
+ * What follows is a description of these indirections, which will help to navigate the Scaladocs easily.
+ *
+ * For instance, consider the base type of all abstract syntax trees: [[scala.reflect.api.Trees#Tree]].
+ * This type is not a class but is abstract and has an upper bound of [[scala.reflect.api.Trees#TreeApi]],
+ * which is a class defining the minimal base interface for all trees.
+ *
+ * For a more interesting tree type, consider [[scala.reflect.api.Trees#If]] representing if-expressions.
+ * It is defined next to a value `If` of type [[scala.reflect.api.Trees#IfExtractor]].
+ * This value serves as the companion object defining a factory method `apply` and a corresponding `unapply`
+ * for pattern matching.
+ *
+ * {{{
+ * import scala.reflect.runtime.universe._
+ * val cond = reify{ condition }.tree // <- just some tree representing a condition
+ * val body = Literal(Constant(1))
+ * val other = Literal(Constant(2))
+ * val iftree = If(cond,body,other)
+ * }}}
+ *
+ * is equivalent to
+ *
+ * {{{
+ * import scala.reflect.runtime.universe._
+ * val iftree = reify{ if( condition ) 1 else 2 }.tree
+ * }}}
+ *
+ * and can be pattern matched as
+ *
+ * {{{
+ * iftree match { case If(cond,body,other) => ... }
+ * }}}
+ *
+ * Moreover, there is an implicit value [[scala.reflect.api.Trees#IfTag]] of type
+ * `ClassTag[If]` that is used by the Scala compiler so that we can indeed pattern match on `If`:
+ * {{{
+ * iftree match { case _:If => ... }
+ * }}}
+ * Without the given implicit value, this pattern match would raise an "unchecked" warning at compile time
+ * since `If` is an abstract type that gets erased at runtime. See [[scala.reflect.ClassTag]] for details.
+ *
+ * To summarize: each tree type `X` (and similarly for other types such as `Type` or `Symbol`) is represented
+ * by an abstract type `X`, optionally together with a class `XApi` that defines `X`'s' interface.
+ * `X`'s companion object, if it exists, is represented by a value `X` that is of type `XExtractor`.
+ * Moreover, for each type `X`, there is a value `XTag` of type `ClassTag[X]` that allows to pattern match on `X`.
+ */
+package object api {
- private[scala] def materializeWeakTypeTag[T](u: base.Universe): u.WeakTypeTag[T] = ??? // macro
- private[scala] def materializeTypeTag[T](u: base.Universe): u.TypeTag[T] = ??? // macro
-}
+ // anchors for materialization macros emitted during tag materialization in Implicits.scala
+ // implementation is hardwired into `scala.reflect.reify.Taggers`
+ // using the mechanism implemented in `scala.tools.reflect.FastTrack`
+ // todo. once we have implicit macros for tag generation, we can remove these anchors
+ private[scala] def materializeWeakTypeTag[T](u: ApiUniverse): u.WeakTypeTag[T] = ??? // macro
+ private[scala] def materializeTypeTag[T](u: ApiUniverse): u.TypeTag[T] = ??? // macro
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index f7371f4180..9f41f0336e 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -3,9 +3,9 @@ package internal
import Flags._
-trait BuildUtils extends base.BuildUtils { self: SymbolTable =>
+trait BuildUtils { self: SymbolTable =>
- class BuildImpl extends BuildBase {
+ class BuildImpl extends BuildApi {
def selectType(owner: Symbol, name: String): TypeSymbol =
select(owner, newTypeName(name)).asType
@@ -64,5 +64,5 @@ trait BuildUtils extends base.BuildUtils { self: SymbolTable =>
def setSymbol[T <: Tree](tree: T, sym: Symbol): T = { tree.setSymbol(sym); tree }
}
- val build: BuildBase = new BuildImpl
+ val build: BuildApi = new BuildImpl
}
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 08cf97673f..2db8c29a63 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -10,7 +10,7 @@ import scala.annotation.{ switch, meta }
import scala.collection.{ mutable, immutable }
import Flags._
import PartialFunction._
-import scala.reflect.base.{Universe => BaseUniverse}
+import scala.reflect.api.{Universe => ApiUniverse}
trait Definitions extends api.StandardDefinitions {
self: SymbolTable =>
@@ -484,7 +484,6 @@ trait Definitions extends api.StandardDefinitions {
// scala.reflect
lazy val ReflectPackage = requiredModule[scala.reflect.`package`.type]
- def ReflectBasis = getMemberValue(ReflectPackage, nme.basis)
lazy val ReflectApiPackage = getPackageObjectIfDefined("scala.reflect.api") // defined in scala-reflect.jar, so we need to be careful
lazy val ReflectRuntimePackage = getPackageObjectIfDefined("scala.reflect.runtime") // defined in scala-reflect.jar, so we need to be careful
def ReflectRuntimeUniverse = if (ReflectRuntimePackage != NoSymbol) getMemberValue(ReflectRuntimePackage, nme.universe) else NoSymbol
@@ -497,31 +496,31 @@ trait Definitions extends api.StandardDefinitions {
lazy val OptManifestClass = requiredClass[scala.reflect.OptManifest[_]]
lazy val NoManifest = requiredModule[scala.reflect.NoManifest.type]
- lazy val ExprsClass = requiredClass[scala.reflect.base.Exprs]
- lazy val ExprClass = getMemberClass(ExprsClass, tpnme.Expr)
- def ExprSplice = getMemberMethod(ExprClass, nme.splice)
- def ExprValue = getMemberMethod(ExprClass, nme.value)
- lazy val ExprModule = getMemberModule(ExprsClass, nme.Expr)
-
- lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]]
- lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]]
- lazy val TypeTagsClass = requiredClass[scala.reflect.base.TypeTags]
- lazy val WeakTypeTagClass = getMemberClass(TypeTagsClass, tpnme.WeakTypeTag)
- lazy val WeakTypeTagModule = getMemberModule(TypeTagsClass, nme.WeakTypeTag)
- lazy val TypeTagClass = getMemberClass(TypeTagsClass, tpnme.TypeTag)
- lazy val TypeTagModule = getMemberModule(TypeTagsClass, nme.TypeTag)
+ lazy val ExprsClass = getClassIfDefined("scala.reflect.api.Exprs") // defined in scala-reflect.jar, so we need to be careful
+ lazy val ExprClass = if (ExprsClass != NoSymbol) getMemberClass(ExprsClass, tpnme.Expr) else NoSymbol
+ def ExprSplice = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.splice) else NoSymbol
+ def ExprValue = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.value) else NoSymbol
+ lazy val ExprModule = if (ExprsClass != NoSymbol) getMemberModule(ExprsClass, nme.Expr) else NoSymbol
+
+ lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]]
+ lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]]
+ lazy val TypeTagsClass = getClassIfDefined("scala.reflect.api.TypeTags") // defined in scala-reflect.jar, so we need to be careful
+ lazy val WeakTypeTagClass = if (TypeTagsClass != NoSymbol) getMemberClass(TypeTagsClass, tpnme.WeakTypeTag) else NoSymbol
+ lazy val WeakTypeTagModule = if (TypeTagsClass != NoSymbol) getMemberModule(TypeTagsClass, nme.WeakTypeTag) else NoSymbol
+ lazy val TypeTagClass = if (TypeTagsClass != NoSymbol) getMemberClass(TypeTagsClass, tpnme.TypeTag) else NoSymbol
+ lazy val TypeTagModule = if (TypeTagsClass != NoSymbol) getMemberModule(TypeTagsClass, nme.TypeTag) else NoSymbol
def materializeClassTag = getMemberMethod(ReflectPackage, nme.materializeClassTag)
def materializeWeakTypeTag = if (ReflectApiPackage != NoSymbol) getMemberMethod(ReflectApiPackage, nme.materializeWeakTypeTag) else NoSymbol
def materializeTypeTag = if (ReflectApiPackage != NoSymbol) getMemberMethod(ReflectApiPackage, nme.materializeTypeTag) else NoSymbol
- lazy val BaseUniverseClass = requiredClass[scala.reflect.base.Universe]
- def BaseUniverseReify = getMemberMethod(BaseUniverseClass, nme.reify)
+ lazy val ApiUniverseClass = getClassIfDefined("scala.reflect.api.Universe") // defined in scala-reflect.jar, so we need to be careful
+ def ApiUniverseReify = if (ApiUniverseClass != NoSymbol) getMemberMethod(ApiUniverseClass, nme.reify) else NoSymbol
lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful
- lazy val MirrorOfClass = requiredClass[scala.reflect.base.MirrorOf[_]]
+ lazy val MirrorOfClass = getClassIfDefined("scala.reflect.api.MirrorOf") // defined in scala-reflect.jar, so we need to be careful
- lazy val TypeCreatorClass = requiredClass[scala.reflect.base.TypeCreator]
- lazy val TreeCreatorClass = requiredClass[scala.reflect.base.TreeCreator]
+ lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful
+ lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful
lazy val MacroContextClass = getClassIfDefined("scala.reflect.macros.Context") // defined in scala-reflect.jar, so we need to be careful
def MacroContextPrefix = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.prefix) else NoSymbol
@@ -529,10 +528,6 @@ trait Definitions extends api.StandardDefinitions {
def MacroContextUniverse = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.universe) else NoSymbol
def MacroContextMirror = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.mirror) else NoSymbol
lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl]
- lazy val MacroInternalPackage = getPackageObject("scala.reflect.macros.internal")
- def MacroInternal_materializeClassTag = getMemberMethod(MacroInternalPackage, nme.materializeClassTag)
- def MacroInternal_materializeWeakTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeWeakTypeTag)
- def MacroInternal_materializeTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeTypeTag)
lazy val StringContextClass = requiredClass[scala.StringContext]
def StringContext_f = getMemberMethod(StringContextClass, nme.f)
@@ -546,8 +541,8 @@ trait Definitions extends api.StandardDefinitions {
lazy val NoneModule: ModuleSymbol = requiredModule[scala.None.type]
lazy val SomeModule: ModuleSymbol = requiredModule[scala.Some.type]
- def compilerTypeFromTag(tt: BaseUniverse # WeakTypeTag[_]): Type = tt.in(rootMirror).tpe
- def compilerSymbolFromTag(tt: BaseUniverse # WeakTypeTag[_]): Symbol = tt.in(rootMirror).tpe.typeSymbol
+ def compilerTypeFromTag(tt: ApiUniverse # WeakTypeTag[_]): Type = tt.in(rootMirror).tpe
+ def compilerSymbolFromTag(tt: ApiUniverse # WeakTypeTag[_]): Symbol = tt.in(rootMirror).tpe.typeSymbol
// The given symbol represents either String.+ or StringAdd.+
def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+
diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala
index 385e45997b..89332d0ae5 100644
--- a/src/reflect/scala/reflect/internal/Scopes.scala
+++ b/src/reflect/scala/reflect/internal/Scopes.scala
@@ -41,7 +41,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
* This is necessary because when run from reflection every scope needs to have a
* SynchronizedScope as mixin.
*/
- class Scope protected[Scopes] (initElems: ScopeEntry = null, initFingerPrints: Long = 0L) extends ScopeBase with MemberScopeBase {
+ class Scope protected[Scopes] (initElems: ScopeEntry = null, initFingerPrints: Long = 0L) extends ScopeApi with MemberScopeApi {
protected[Scopes] def this(base: Scope) = {
this(base.elems)
diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala
index 5f6a3bf777..5c4d1f7e28 100644
--- a/src/reflect/scala/reflect/internal/StdAttachments.scala
+++ b/src/reflect/scala/reflect/internal/StdAttachments.scala
@@ -8,7 +8,7 @@ trait StdAttachments {
* Common code between reflect-internal Symbol and Tree related to Attachments.
*/
trait Attachable {
- protected var rawatt: base.Attachments { type Pos = Position } = NoPosition
+ protected var rawatt: scala.reflect.api.Attachments { type Pos = Position } = NoPosition
def attachments = rawatt
def updateAttachment[T: ClassTag](attachment: T): this.type = { rawatt = rawatt.update(attachment); this }
def removeAttachment[T: ClassTag]: this.type = { rawatt = rawatt.remove[T]; this }
diff --git a/src/reflect/scala/reflect/internal/StdCreators.scala b/src/reflect/scala/reflect/internal/StdCreators.scala
index 3e6b7c1ab4..eba583d4b5 100644
--- a/src/reflect/scala/reflect/internal/StdCreators.scala
+++ b/src/reflect/scala/reflect/internal/StdCreators.scala
@@ -1,20 +1,20 @@
package scala.reflect
package internal
-import scala.reflect.base.{TreeCreator, TypeCreator}
-import scala.reflect.base.{Universe => BaseUniverse}
+import scala.reflect.api.{TreeCreator, TypeCreator}
+import scala.reflect.api.{Universe => ApiUniverse}
trait StdCreators {
self: SymbolTable =>
case class FixedMirrorTreeCreator(mirror: MirrorOf[StdCreators.this.type], tree: Tree) extends TreeCreator {
- def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Tree =
+ def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Tree =
if (m eq mirror) tree.asInstanceOf[U # Tree]
else throw new IllegalArgumentException(s"Expr defined in $mirror cannot be migrated to other mirrors.")
}
case class FixedMirrorTypeCreator(mirror: MirrorOf[StdCreators.this.type], tpe: Type) extends TypeCreator {
- def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type =
+ def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Type =
if (m eq mirror) tpe.asInstanceOf[U # Type]
else throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.")
}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 8e00ef74e5..2cdfb05e77 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -633,7 +633,6 @@ trait StdNames {
val asInstanceOf_Ob : NameType = "$asInstanceOf"
val assert_ : NameType = "assert"
val assume_ : NameType = "assume"
- val basis : NameType = "basis"
val box: NameType = "box"
val build : NameType = "build"
val bytes: NameType = "bytes"
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 74f4769fec..d44790fd59 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -10,7 +10,6 @@ import scala.collection.{ mutable, immutable }
import scala.collection.mutable.ListBuffer
import util.Statistics
import Flags._
-import base.Attachments
import scala.annotation.tailrec
import scala.tools.nsc.io.AbstractFile
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index f953e9b757..ebf0998573 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -272,9 +272,6 @@ abstract class TreeGen extends macros.TreeBuilder {
def mkOr(tree1: Tree, tree2: Tree): Tree =
Apply(Select(tree1, Boolean_or), List(tree2))
- def mkBasisUniverseRef: Tree =
- mkAttributedRef(ReflectBasis) setType singleType(ReflectBasis.owner.thisPrefix, ReflectBasis)
-
def mkRuntimeUniverseRef: Tree = {
assert(ReflectRuntimeUniverse != NoSymbol)
mkAttributedRef(ReflectRuntimeUniverse) setType singleType(ReflectRuntimeUniverse.owner.thisPrefix, ReflectRuntimeUniverse)
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index 8e91431220..8145ed2263 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -7,7 +7,6 @@ package scala.reflect
package internal
import Flags._
-import base.Attachments
import scala.collection.mutable.{ListBuffer, LinkedHashSet}
import util.Statistics
diff --git a/src/reflect/scala/reflect/internal/package.scala b/src/reflect/scala/reflect/internal/package.scala
index 99b837152d..63568f6a6b 100644
--- a/src/reflect/scala/reflect/internal/package.scala
+++ b/src/reflect/scala/reflect/internal/package.scala
@@ -2,5 +2,5 @@ package scala.reflect
package object internal {
- type MirrorOf[U <: base.Universe with Singleton] = base.MirrorOf[U]
+ type MirrorOf[U <: scala.reflect.api.Universe with Singleton] = scala.reflect.api.MirrorOf[U]
}
diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala
index 0268881be7..1621fb84d4 100644
--- a/src/reflect/scala/reflect/internal/util/Position.scala
+++ b/src/reflect/scala/reflect/internal/util/Position.scala
@@ -7,7 +7,7 @@
package scala.reflect.internal.util
import scala.reflect.ClassTag
-import scala.reflect.base.Attachments
+import scala.reflect.api.Attachments
import scala.reflect.api.PositionApi
object Position {
diff --git a/src/reflect/scala/reflect/macros/Reifiers.scala b/src/reflect/scala/reflect/macros/Reifiers.scala
index bdc6687edc..c2a6c5be05 100644
--- a/src/reflect/scala/reflect/macros/Reifiers.scala
+++ b/src/reflect/scala/reflect/macros/Reifiers.scala
@@ -6,11 +6,6 @@ import scala.reflect.api.PositionApi
trait Reifiers {
self: Context =>
- /** Reification prefix that refers to the base reflexive universe, ``scala.reflect.basis''.
- * Providing it for the ``prefix'' parameter of ``reifyTree'' or ``reifyType'' will create a tree that can be inspected at runtime.
- */
- val basisUniverse: Tree
-
/** Reification prefix that refers to the runtime reflexive universe, ``scala.reflect.runtime.universe''.
* Providing it for the ``prefix'' parameter of ``reifyTree'' or ``reifyType'' will create a full-fledged tree that can be inspected at runtime.
*/
@@ -20,7 +15,7 @@ trait Reifiers {
* For more information and examples see the documentation for ``Universe.reify''.
*
* The produced tree will be bound to the specified ``universe'' and ``mirror''.
- * Possible values for ``universe'' include ``basisUniverse'' and ``runtimeUniverse''.
+ * Possible values for ``universe'' include ``runtimeUniverse''.
* Possible values for ``mirror'' include ``EmptyTree'' (in that case the reifier will automatically pick an appropriate mirror).
*
* This function is deeply connected to ``Universe.reify'', a macro that reifies arbitrary expressions into runtime trees.
diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala
index 7fa2e7cbae..f84c11ee63 100644
--- a/src/reflect/scala/reflect/macros/Universe.scala
+++ b/src/reflect/scala/reflect/macros/Universe.scala
@@ -7,7 +7,7 @@ abstract class Universe extends scala.reflect.api.Universe {
trait AttachableApi {
/** ... */
- def attachments: base.Attachments { type Pos = Position }
+ def attachments: scala.reflect.api.Attachments { type Pos = Position }
/** ... */
def updateAttachment[T: ClassTag](attachment: T): AttachableApi.this.type
diff --git a/src/reflect/scala/reflect/macros/package.scala b/src/reflect/scala/reflect/macros/package.scala
index 06ce0b3244..df93785d40 100644
--- a/src/reflect/scala/reflect/macros/package.scala
+++ b/src/reflect/scala/reflect/macros/package.scala
@@ -2,5 +2,5 @@ package scala.reflect
package object macros {
- type MirrorOf[U <: base.Universe with Singleton] = base.MirrorOf[U]
+ type MirrorOf[U <: scala.reflect.api.Universe with Singleton] = scala.reflect.api.MirrorOf[U]
}