summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Vogt <christopher.vogt@epfl.ch>2012-09-19 12:15:53 +0200
committerChristopher Vogt <christopher.vogt@epfl.ch>2012-09-19 12:15:53 +0200
commitecbb25a311daee09be6ec67bd482d5d6e1ee0fea (patch)
tree2db43e3ada0c3b6879f6fba1eb6905692676128c
parentbbd2e43b1ddd244f8f67c951b9009444efa19391 (diff)
downloadscala-ecbb25a311daee09be6ec67bd482d5d6e1ee0fea.tar.gz
scala-ecbb25a311daee09be6ec67bd482d5d6e1ee0fea.tar.bz2
scala-ecbb25a311daee09be6ec67bd482d5d6e1ee0fea.zip
improved/fixed reflection docs based on comments
-rw-r--r--src/library/scala/reflect/ClassTag.scala4
-rw-r--r--src/library/scala/reflect/base/Annotations.scala21
-rw-r--r--src/library/scala/reflect/base/Attachments.scala14
-rw-r--r--src/library/scala/reflect/base/Exprs.scala23
-rw-r--r--src/library/scala/reflect/base/MirrorOf.scala2
-rw-r--r--src/library/scala/reflect/base/Mirrors.scala5
-rw-r--r--src/library/scala/reflect/base/Names.scala8
-rw-r--r--src/library/scala/reflect/base/StandardDefinitions.scala2
-rw-r--r--src/library/scala/reflect/base/Symbols.scala6
-rw-r--r--src/library/scala/reflect/base/TreeCreator.scala20
-rw-r--r--src/library/scala/reflect/base/Trees.scala34
-rw-r--r--src/library/scala/reflect/base/TypeCreator.scala20
-rw-r--r--src/library/scala/reflect/base/TypeTags.scala17
-rw-r--r--src/library/scala/reflect/base/Universe.scala10
-rw-r--r--src/library/scala/reflect/package.scala39
15 files changed, 155 insertions, 70 deletions
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
index 0bafa7c505..1a574836c0 100644
--- a/src/library/scala/reflect/ClassTag.scala
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -9,10 +9,10 @@ import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass }
*
* If an implicit value of type ClassTag[T] is requested, the compiler will create one.
* The runtime class (i.e. the erasure, a java.lang.Class on the JVM) of T can be accessed
- * via the `runtimeClass` field. References to type parameters or abstract types are
+ * via the `runtimeClass` field. References to type parameters or abstract type members are
* replaced by the concrete types if ClassTags are available for them.
*
- * Besides accessing the erasure, a ClassTag knows how instantiate single- and multi-
+ * Besides accessing the erasure, a ClassTag knows how to instantiate single- and multi-
* dimensional `Arrays` where the element type is unknown at compile time.
*
* [[scala.reflect.ClassTag]] corresponds to a previous concept of [[scala.reflect.ClassManifest]].
diff --git a/src/library/scala/reflect/base/Annotations.scala b/src/library/scala/reflect/base/Annotations.scala
index c6ef7b721c..107443f09b 100644
--- a/src/library/scala/reflect/base/Annotations.scala
+++ b/src/library/scala/reflect/base/Annotations.scala
@@ -10,8 +10,8 @@ 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.Annotation]] or [[scala.annotation.StaticAnnotation]]
- * but not [[scala.annotation.ClassfileAnnotation]] or ''Java annotations'', which conform to [[scala.annotation.ClassfileAnnotation]].
+ * 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
@@ -24,17 +24,16 @@ trait Annotations { self: Universe =>
/** The constructor/deconstructor for `Annotation` instances. */
val Annotation: AnnotationExtractor
- /** An extractor class to create and pattern match with syntax `Annotation(atp, args, javaArgs)`.
- * Here, `atp` is the annotation type, `args` the arguments, and `javaArgs` the annotation's key-value
+ /** 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 written to the classfile as Java annotations if `atp` conforms to
- * `ClassfileAnnotation`. Annotations are pickled, i.e., written to scala symtab attribute in the classfile,
- * if `atp` inherits from `StaticAnnotation` but not `ClassfileAnnotation`.
+ * 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 `args` and `javaArgs` is empty. Arguments in
- * `args` are represented as typed trees. Note that these trees are not transformed by any phases
- * following the type-checker. For Java annotations, `args` is empty and arguments are stored in
+ * 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 {
@@ -85,7 +84,7 @@ trait Annotations { self: Universe =>
def unapply(arg: ArrayArgument): Option[Array[JavaArgument]]
}
- /** A nested argument to a Java annotation as `@Nested` in `@Outer(@Nested)`.
+ /** A nested annotation argument to a Java annotation as `@Nested` in `@Outer(@Nested)`.
*/
type NestedArgument >: Null <: AnyRef with JavaArgument
diff --git a/src/library/scala/reflect/base/Attachments.scala b/src/library/scala/reflect/base/Attachments.scala
index 0082066fdb..479ab9a857 100644
--- a/src/library/scala/reflect/base/Attachments.scala
+++ b/src/library/scala/reflect/base/Attachments.scala
@@ -1,8 +1,9 @@
package scala.reflect
package base
-/** Attachments is a generalisation of Position. Typically it stores a Position of a tree, but this can be extended to
- * encompass arbitrary payloads.
+/** Attachments 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.
@@ -18,7 +19,7 @@ abstract class Attachments { self =>
/** Creates a copy of this attachment with the position replaced by `newPos` */
def withPos(newPos: Pos): Attachments { type Pos = self.Pos }
- /** The underlying payload. */
+ /** 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) =
@@ -28,11 +29,14 @@ abstract class Attachments { self =>
def get[T: ClassTag]: Option[T] =
(all filter matchesTag[T]).headOption.asInstanceOf[Option[T]]
- /** Creates a copy of this attachment with a new payload added */
+ /** 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 all payloads of the given class type `T` removed. */
+ /** 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 }]
diff --git a/src/library/scala/reflect/base/Exprs.scala b/src/library/scala/reflect/base/Exprs.scala
index 0fd383e8b2..bd15c65711 100644
--- a/src/library/scala/reflect/base/Exprs.scala
+++ b/src/library/scala/reflect/base/Exprs.scala
@@ -12,7 +12,10 @@ trait Exprs { self: Universe =>
trait Expr[+T] extends Equals with Serializable {
val mirror: Mirror
/**
- * Migrates the expression into another universe given its corresponding 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]
@@ -32,6 +35,7 @@ trait Exprs { self: Universe =>
/**
* 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.
@@ -52,10 +56,23 @@ trait Exprs { self: Universe =>
* {{{
* reify{ expr.foo }
* }}}
- * because expr of type Expr[T] does not have a method foo.
+ * because expr of type Expr[T] itself does not have a method foo.
*/
def splice: T
- // TODO: document this
+ /**
+ * 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 */
diff --git a/src/library/scala/reflect/base/MirrorOf.scala b/src/library/scala/reflect/base/MirrorOf.scala
index 6115a622bc..4e54a2fae7 100644
--- a/src/library/scala/reflect/base/MirrorOf.scala
+++ b/src/library/scala/reflect/base/MirrorOf.scala
@@ -24,7 +24,7 @@ abstract class MirrorOf[U <: base.Universe with Singleton] {
/** The module symbol of the `_root_` package */
def RootPackage: U#ModuleSymbol
- /** The class symbol of the default (unnamed) package */
+ /** The module class symbol of the default (unnamed) package */
def EmptyPackageClass: U#ClassSymbol
/** The module symbol of the default (unnamed) package */
diff --git a/src/library/scala/reflect/base/Mirrors.scala b/src/library/scala/reflect/base/Mirrors.scala
index 8cb6811dca..e38a3d1cdd 100644
--- a/src/library/scala/reflect/base/Mirrors.scala
+++ b/src/library/scala/reflect/base/Mirrors.scala
@@ -15,9 +15,8 @@ trait Mirrors {
/** The base type of all mirrors of this universe */
type Mirror >: Null <: MirrorOf[self.type]
- /** The roor 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. The root package of this mirror contains the root
- * packages of all other mirrors of this universe as members.
+ /** 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
}
diff --git a/src/library/scala/reflect/base/Names.scala b/src/library/scala/reflect/base/Names.scala
index 8afdb8f69b..b02038a920 100644
--- a/src/library/scala/reflect/base/Names.scala
+++ b/src/library/scala/reflect/base/Names.scala
@@ -37,10 +37,10 @@ trait Names {
/** The base API that all names support */
abstract class NameBase {
- /** Checks weather the name is a a term name */
+ /** Checks wether the name is a a term name */
def isTermName: Boolean
- /** Checks weather the name is a a type name */
+ /** Checks wether the name is a a type name */
def isTypeName: Boolean
/** Returns a term name that wraps the same string as `this` */
@@ -58,11 +58,11 @@ trait Names {
*/
def newTypeName(s: String): TypeName
- /** Wraps the empty string
+ /** Wraps the empty string. Can be used as the null object for term name.
*/
def EmptyTermName: TermName = newTermName("")
- /** Wraps the empty string
+ /** Wraps the empty string. Can be used as the null object for term name.
*/
def EmptyTypeName: TypeName = EmptyTermName.toTypeName
}
diff --git a/src/library/scala/reflect/base/StandardDefinitions.scala b/src/library/scala/reflect/base/StandardDefinitions.scala
index 6d85ae9d2a..4df8501b3d 100644
--- a/src/library/scala/reflect/base/StandardDefinitions.scala
+++ b/src/library/scala/reflect/base/StandardDefinitions.scala
@@ -20,7 +20,7 @@ trait StandardDefinitions {
/** The class symbol of package `scala`. */
def ScalaPackageClass: ClassSymbol
- /** The module symbol of package `scala`. */
+ /** The module class symbol of package `scala`. */
def ScalaPackage: ModuleSymbol
// top types
diff --git a/src/library/scala/reflect/base/Symbols.scala b/src/library/scala/reflect/base/Symbols.scala
index efdd4cb19e..4a1eef014c 100644
--- a/src/library/scala/reflect/base/Symbols.scala
+++ b/src/library/scala/reflect/base/Symbols.scala
@@ -86,10 +86,10 @@ trait Symbols { self: Universe =>
* 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.mirror.RootClass]]
- * and the Scala root object [[scala.reflect.api.mirror.RootPackage]] is `NoSymbol`.
+ * The owner of the Scala root class [[scala.reflect.base.MirrorOf.RootClass]]
+ * and the Scala root object [[scala.reflect.base.MirrorOf.RootPackage]] is `NoSymbol`.
* Every other symbol has a chain of owners that ends in
- * [[scala.reflect.api.mirror.RootClass]].
+ * [[scala.reflect.base.MirrorOf.RootClass]].
*/
def owner: Symbol
diff --git a/src/library/scala/reflect/base/TreeCreator.scala b/src/library/scala/reflect/base/TreeCreator.scala
index c9c8de2307..5de0094f1f 100644
--- a/src/library/scala/reflect/base/TreeCreator.scala
+++ b/src/library/scala/reflect/base/TreeCreator.scala
@@ -1,6 +1,26 @@
package scala.reflect
package base
+/** 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/library/scala/reflect/base/Trees.scala b/src/library/scala/reflect/base/Trees.scala
index 666870cb10..428b493478 100644
--- a/src/library/scala/reflect/base/Trees.scala
+++ b/src/library/scala/reflect/base/Trees.scala
@@ -88,7 +88,7 @@ trait Trees { self: Universe =>
/** The empty tree */
val EmptyTree: Tree
- /** A tree for a term. Not all trees are TermTrees; use isTerm
+ /** A tree for a term. Not all trees representing terms are TermTrees; use isTerm
* to reliably identify terms.
*/
type TermTree >: Null <: AnyRef with Tree
@@ -98,7 +98,7 @@ trait Trees { self: Universe =>
*/
implicit val TermTreeTag: ClassTag[TermTree]
- /** A tree for a type. Not all trees are TypTrees; use isType
+ /** A tree for a type. Not all trees representing types are TypTrees; use isType
* to reliably identify types.
*/
type TypTree >: Null <: AnyRef with Tree
@@ -250,7 +250,6 @@ trait Trees { self: Universe =>
*/
implicit val ValOrDefDefTag: ClassTag[ValOrDefDef]
- // FIXME: document how ValDef in self-types can be recognized. (Only private modifier is set there.)
/** Broadly speaking, a value definition. All these are encoded as ValDefs:
*
* - immutable values, e.g. "val x"
@@ -513,7 +512,7 @@ trait Trees { self: Universe =>
/** Case clause in a pattern match.
* (except for occurrences in switch statements).
- * Eliminated by compiler phases patmat/explicitouter.
+ * 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
@@ -538,7 +537,10 @@ trait Trees { self: Universe =>
def unapply(caseDef: CaseDef): Option[(Tree, Tree, Tree)]
}
- /** Alternatives of patterns, eliminated by compiler phases patmat/explicitouter, except for
+ /** 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
@@ -562,7 +564,8 @@ trait Trees { self: Universe =>
}
/** Repetition of pattern.
- * Eliminated by compiler phase patmat/explicitouter.
+ *
+ * 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
@@ -585,7 +588,8 @@ trait Trees { self: Universe =>
}
/** Bind a variable to a rhs pattern.
- * Eliminated by compiler phase patmat/explicitouter.
+ *
+ * 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
@@ -610,12 +614,9 @@ trait Trees { self: Universe =>
def unapply(bind: Bind): Option[(Name, Tree)]
}
- // TODO: evaluate if UnApply can be removed or at least moved out of reflection.
/**
* Used to represent `unapply` methods in pattern matching.
*
- * Introduced by typer, eliminated by patmat/explicitouter.
- *
* For example:
* {{{
* 2 match { case Foo(x) => x }
@@ -637,6 +638,8 @@ trait Trees { self: Universe =>
* 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
@@ -705,7 +708,7 @@ trait Trees { self: Universe =>
*
* vparams => body
*
- * The symbol of a Function is a synthetic TermSymbol having its name set to nme.ANON_FUN_NAME.
+ * The symbol of a Function is a synthetic TermSymbol.
* It is the owner of the function's parameters.
*/
abstract class FunctionExtractor {
@@ -786,10 +789,10 @@ trait Trees { self: Universe =>
def unapply(if_ : If): Option[(Tree, Tree, Tree)]
}
- /** - Pattern matching expression (before compiler phase explicitouter)
- * - Switch statements (after compiler phase explicitouter)
+ /** - 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, cases will satisfy the following constraints:
+ * 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))`
@@ -1002,9 +1005,8 @@ trait Trees { self: Universe =>
def unapply(apply: Apply): Option[(Tree, List[Tree])]
}
- // TODO: what is it used for exactly? extend docs!
/** Super reference, where `qual` is the corresponding `this` reference.
- * A super reference C.super[M] is represented as Super(This(C), M).
+ * A super reference `C.super[M]` is represented as `Super(This(C), M)`.
*/
type Super >: Null <: TermTree
diff --git a/src/library/scala/reflect/base/TypeCreator.scala b/src/library/scala/reflect/base/TypeCreator.scala
index 8a14e53dd3..0260fe1410 100644
--- a/src/library/scala/reflect/base/TypeCreator.scala
+++ b/src/library/scala/reflect/base/TypeCreator.scala
@@ -1,6 +1,26 @@
package scala.reflect
package base
+/** 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/library/scala/reflect/base/TypeTags.scala b/src/library/scala/reflect/base/TypeTags.scala
index eeda6cb143..db9fa95553 100644
--- a/src/library/scala/reflect/base/TypeTags.scala
+++ b/src/library/scala/reflect/base/TypeTags.scala
@@ -20,16 +20,14 @@ import scala.language.implicitConversions
/**
* A type tag encapsulates a representation of type T.
*
- * Type tags replace the pre-2.10 concept of a [[scala.reflect.Manifest]] and are much better integrated with reflection.
+ * 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.base.Universe#TypeTag]] and [[scala.reflect.base.Universe#WeakTypeTag]].
*
- * @see scala.reflect.ClassTag
- * @see scala.reflect.base.Universe#TypeTag
- * @see scala.reflect.base.Universe#WeakTypeTag
+ * @see [[scala.reflect.ClassTag]], [[scala.reflect.base.Universe#TypeTag]], [[scala.reflect.base.Universe#WeakTypeTag]]
*
* Examples:
* {{{
@@ -82,8 +80,9 @@ import scala.language.implicitConversions
*
* {{{
* tag.in( other_mirror )
- * }}}
- *
+ * }}}
+ *
+ * See [[scala.reflect.base.TypeTags#WeakTypeTag.in]]
*
* === WeakTypeTag vs TypeTag ===
*
@@ -163,6 +162,9 @@ trait TypeTags { self: 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]
@@ -306,7 +308,7 @@ trait TypeTags { self: Universe =>
}
}
- private class PredefTypeTag[T](_tpe: Type, copyIn: Universe => Universe # TypeTag[T]) extends TypeTagImpl[T](rootMirror, new PredefTypeCreator(copyIn)) {
+ 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)
}
@@ -314,6 +316,7 @@ trait TypeTags { self: Universe =>
/**
* Shortcut for `implicitly[WeakTypeTag[T]]`
*/
+ def weakTypeTag[T](implicit attag: WeakTypeTag[T]) = attag
/**
* Shortcut for `implicitly[TypeTag[T]]`
diff --git a/src/library/scala/reflect/base/Universe.scala b/src/library/scala/reflect/base/Universe.scala
index be1b60933a..0b5d5ed685 100644
--- a/src/library/scala/reflect/base/Universe.scala
+++ b/src/library/scala/reflect/base/Universe.scala
@@ -28,13 +28,13 @@ abstract class Universe extends Symbols
* reify{ five.splice + 4 } // Apply( Select( Literal(Constant(5)), newTermName("$plus")), List( Literal(Constant(4)) ) )
* }}}
*
- * The produced tree is path dependent on the Universe `refiy` was called from.
+ * The produced tree is path dependent on the Universe `reify` was called from.
*
- * Use [[splice]] to embed an existing expression into a reify call. Use [[Expr]] to turn a [[Tree]] into an expression that can be spliced.
+ * Use [[scala.reflect.base.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 ==
*
- * `refiy` is implemented as a macro, which given an expression, generates a tree that when compiled and executed produces the original tree.
+ * `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
*
@@ -71,10 +71,8 @@ abstract class Universe extends Symbols
* 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 FreeVar
+ * - 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
- * - Since reified trees can be compiled outside of the scope they've been created in,
- * special measures are taken to ensure that all members accessed in the reifee remain visible
*/
// implementation is hardwired to `scala.reflect.reify.Taggers`
// using the mechanism implemented in `scala.tools.reflect.FastTrack`
diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala
index e78ec7599a..046491ae10 100644
--- a/src/library/scala/reflect/package.scala
+++ b/src/library/scala/reflect/package.scala
@@ -3,23 +3,23 @@ package scala
/**
* The base package of Scala's reflection library.
*
- * The refection library is structured according to the 'cake pattern'. The base layer
+ * The reflection library is structured according to the 'cake pattern'. The base layer
* resides in package [[scala.reflect.base]] and defines an interface to the following main types:
*
* - [[scala.reflect.base.Types#Type Types]] represent types
- * - [[scala.reflect.base.Symbol#Symbol Symbols]] represent definitions
+ * - [[scala.reflect.base.Symbols#Symbol Symbols]] represent definitions
* - [[scala.reflect.base.Trees#Tree Trees]] represent abstract syntax trees
* - [[scala.reflect.base.Names#Name Names]] represent term and type names
- * - [[scala.reflect.base.AnnotationInfos#AnnotationInfo AnnotationInfos]] represent annotations
- * - [[scala.reflect.base.Position#Positions Positions]] represent source positions of tree nodes
+ * - [[scala.reflect.base.Annotations#Annotation Annotations]] represent annotations
+ * - [[scala.reflect.base.Positions#Position Positions]] represent source positions of tree nodes
* - [[scala.reflect.base.FlagSets#FlagSet FlagSet]] represent sets of flags that apply to symbols and
* definition trees
- * - [[scala.reflect.base.Constansts#Constant Constants]] represent compile-time constants.
+ * - [[scala.reflect.base.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.base.Universe Universe]]. The base 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]].
+ * 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.
@@ -32,10 +32,33 @@ package scala
* It does not come with a class `IfBase`, since it does not add anything to the interface of its upper
* bound `TermTree`. However, it is defined next to a value `If` of type [[scala.reflect.base.Trees#IfExtractor]].
* This value serves as the companion object defining a factory method `apply` and a corresponding `unapply`
- * for pattern matching. Moreover, there is an implicit value [[scala.reflect.base.Trees#IfTag]] of type
+ * 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.base.Trees#IfTag]] of type
* `ClassTag[If]` that is used by the Scala compiler so that we can indeed pattern match on `If`:
* {{{
- * tree match { case ifTree: 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.