summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeather Miller <heather.miller@epfl.ch>2012-10-11 20:31:42 +0200
committerHeather Miller <heather.miller@epfl.ch>2012-10-11 20:31:42 +0200
commite95a00992599f59f7c74bcc171bb290f859ab848 (patch)
treefcafe4836f532311790b32c46180c4222fd933b7
parentb55ca84dbc34f3337d4e95df3a045156d71f77d7 (diff)
downloadscala-e95a00992599f59f7c74bcc171bb290f859ab848.tar.gz
scala-e95a00992599f59f7c74bcc171bb290f859ab848.tar.bz2
scala-e95a00992599f59f7c74bcc171bb290f859ab848.zip
Adds lots of new documentation for TypeTags, Mirrors, Universes and more
Additionally includes improvements, formatting fixes, and link additions and fixes.
-rw-r--r--src/library/scala/reflect/ClassTag.scala35
-rw-r--r--src/reflect/scala/reflect/api/Annotations.scala13
-rw-r--r--src/reflect/scala/reflect/api/Constants.scala76
-rw-r--r--src/reflect/scala/reflect/api/Exprs.scala3
-rw-r--r--src/reflect/scala/reflect/api/FlagSets.scala59
-rw-r--r--src/reflect/scala/reflect/api/Importers.scala34
-rw-r--r--src/reflect/scala/reflect/api/JavaMirrors.scala22
-rw-r--r--src/reflect/scala/reflect/api/Mirror.scala13
-rw-r--r--src/reflect/scala/reflect/api/Mirrors.scala201
-rw-r--r--src/reflect/scala/reflect/api/Names.scala4
-rw-r--r--src/reflect/scala/reflect/api/Position.scala24
-rw-r--r--src/reflect/scala/reflect/api/Printers.scala78
-rw-r--r--src/reflect/scala/reflect/api/StandardDefinitions.scala7
-rw-r--r--src/reflect/scala/reflect/api/StandardNames.scala3
-rw-r--r--src/reflect/scala/reflect/api/TreeCreator.scala2
-rw-r--r--src/reflect/scala/reflect/api/TypeCreator.scala6
-rw-r--r--src/reflect/scala/reflect/api/TypeTags.scala256
-rw-r--r--src/reflect/scala/reflect/api/Universe.scala131
-rw-r--r--src/reflect/scala/reflect/api/package.scala19
-rw-r--r--src/reflect/scala/reflect/runtime/package.scala12
20 files changed, 646 insertions, 352 deletions
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
index 5c2067a548..d699e34ffc 100644
--- a/src/library/scala/reflect/ClassTag.scala
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -5,19 +5,34 @@ import java.lang.{ Class => jClass }
import scala.language.{implicitConversions, existentials}
import scala.runtime.ScalaRunTime.{ arrayClass, arrayElementClass }
-/** A `ClassTag[T]` wraps a runtime class (the erasure) and can create array instances.
+/**
+ *
+ * A `ClassTag[T]` stores the erased class of a given type `T`, accessible via the `runtimeClass`
+ * field. This is particularly useful for instantiating `Array`s whose element types are unknown
+ * at compile time.
+ *
+ * `ClassTag`s are a weaker special case of [[scala.reflect.api.TypeTags#TypeTag]]s, in that they
+ * wrap only the runtime class of a given type, whereas a `TypeTag` contains all static type
+ * information. That is, `ClassTag`s are constructed from knowing only the top-level class of a
+ * type, without necessarily knowing all of its argument types. This runtime information is enough
+ * for runtime `Array` creation.
*
- * 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 type members are
- * replaced by the concrete types if ClassTags are available for them.
+ * For example:
+ * {{{
+ * scala> def mkArray[T : ClassTag](elems: T*) = Array[T](elems: _*)
+ * mkArray: [T](elems: T*)(implicit evidence$1: scala.reflect.ClassTag[T])Array[T]
*
- * 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> mkArray(42, 13)
+ * res0: Array[Int] = Array(42, 13)
*
- * [[scala.reflect.ClassTag]] corresponds to a previous concept of [[scala.reflect.ClassManifest]].
+ * scala> mkArray("Japan","Brazil","Germany")
+ * res1: Array[String] = Array(Japan, Brazil, Germany)
+ * }}}
+ *
+ * See [[scala.reflect.api.TypeTags]] for more examples, or the
+ * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]]
+ * for more details.
*
- * @see [[scala.reflect.api.TypeTags]]
*/
@scala.annotation.implicitNotFound(msg = "No ClassTag available for ${T}")
trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serializable {
@@ -29,7 +44,7 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial
*/
def runtimeClass: jClass[_]
- /** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */
+ /** Produces a `ClassTag` that knows how to instantiate an `Array[Array[T]]` */
def wrap: ClassTag[Array[T]] = ClassTag[Array[T]](arrayClass(runtimeClass))
/** Produces a new array with element type `T` and length `len` */
diff --git a/src/reflect/scala/reflect/api/Annotations.scala b/src/reflect/scala/reflect/api/Annotations.scala
index 1e658228f3..fb353a5520 100644
--- a/src/reflect/scala/reflect/api/Annotations.scala
+++ b/src/reflect/scala/reflect/api/Annotations.scala
@@ -6,11 +6,16 @@ import scala.collection.immutable.ListMap
/** This trait provides annotation support for the reflection API.
*
* The API distinguishes between two kinds of annotations:
- * 1. ''Java annotations'': annotations on definitions produced by the Java compiler, i.e., subtypes of `java.lang.annotation.Annotation` attached to program definitions. When read by Scala reflection, the [[scala.annotation.ClassfileAnnotation]] trait is automatically added as a subclass to every Java annotation.
- * 1. ''Scala annotations'': annotations on definitions or types produced by the Scala compiler.
*
- * When a Scala annotation that inherits from [[scala.annotation.StaticAnnotation]] or [[scala.annotation.ClassfileAnnotation]] is compiled,
- * it is stored as special attributes in the corresponding classfile, and not as a Java annotation. Note that subclassing
+ * <ul>
+ * <li>''Java annotations'': annotations on definitions produced by the Java compiler, i.e., subtypes of [[java.lang.annotation.Annotation]]
+ * attached to program definitions. When read by Scala reflection, the [[scala.annotation.ClassfileAnnotation]] trait
+ * is automatically added as a subclass to every Java annotation.</li>
+ * <li>''Scala annotations'': annotations on definitions or types produced by the Scala compiler.</li>
+ * </ul>
+ *
+ * When a Scala annotation that inherits from [[scala.annotation.StaticAnnotation]] or [[scala.annotation.ClassfileAnnotation]] is compiled,
+ * it is stored as special attributes in the corresponding classfile, and not as a Java annotation. Note that subclassing
* just [[scala.annotation.Annotation]] is not enough to have the corresponding metadata persisted for runtime reflection.
*
* The distinction between Java and Scala annotations is manifested in the contract of [[scala.reflect.api.Annotations#Annotation]], which exposes
diff --git a/src/reflect/scala/reflect/api/Constants.scala b/src/reflect/scala/reflect/api/Constants.scala
index 9e0573f0dc..a92fc5cbb3 100644
--- a/src/reflect/scala/reflect/api/Constants.scala
+++ b/src/reflect/scala/reflect/api/Constants.scala
@@ -7,9 +7,79 @@ package scala.reflect
package api
/**
- * This trait is the [[scala.reflect.api.Universe reflection API]] component that mirrors constant irreducible expressions
- * such as `true`, `0` and `classOf[List]`. Constant values appear in the program abstract syntax tree and in annotation parameters
- * wrapped in [[Constant `Constant`]] case classes.
+ * According to the section 6.24 "Constant Expressions" of the Scala language specification,
+ * certain expressions (dubbed ''constant expressions'') can be evaluated by the Scala compiler at compile-time.
+ *
+ * [[scala.reflect.api.Constants#Constant]] instances represent certain kinds of these expressions
+ * (with values stored in the `value` field and its strongly-typed views named `booleanValue`, `intValue` etc.), namely:
+ * 1. Literals of primitive value classes (bytes, shorts, ints, longs, floats, doubles, chars, booleans and voids).
+ * 1. String literals.
+ * 1. References to classes (typically constructed with [[scala.Predef#classOf]]).
+ * 1. References to enumeration values.
+ *
+ * Such constants are used to represent literals in abstract syntax trees (the [[scala.reflect.api.Trees#Literal]] node)
+ * and literal arguments for Java class file annotations (the [[scala.reflect.api.Annotations#LiteralArgument]] class).
+ *
+ * === Example ===
+ *
+ * The `value` field deserves some explanation. Primitive and string values are represented as themselves, whereas
+ * references to classes and enums are a bit roundabout.
+ *
+ * Class references are represented as instances of [[scala.reflect.api.Types#Type]]
+ * (because when the Scala compiler processes a class reference, the underlying runtime class might not yet have been compiled).
+ * To convert such a reference to a runtime class, one should use the `runtimeClass` method of a mirror such as [[scala.reflect.api.Mirrors#RuntimeMirror]]
+ * (the simplest way to get such a mirror is using [[scala.reflect.runtime.package#currentMirror]]).
+ *
+ * Enumeration value references are represented as instances of [[scala.reflect.api.Symbols#Symbol]], which on JVM point to methods
+ * that return underlying enum values. To inspect an underlying enumeration or to get runtime value of a reference to an enum,
+ * one should use a [[scala.reflect.api.Mirrors#RuntimeMirror]] (the simplest way to get such a mirror is again [[scala.reflect.runtime.package#currentMirror]]).
+
+ * {{{
+ * enum JavaSimpleEnumeration { FOO, BAR }
+ *
+ * import java.lang.annotation.*;
+ * @Retention(RetentionPolicy.RUNTIME)
+ * @Target({ElementType.TYPE})
+ * public @interface JavaSimpleAnnotation {
+ * Class<?> classRef();
+ * JavaSimpleEnumeration enumRef();
+ * }
+ *
+ * @JavaSimpleAnnotation(
+ * classRef = JavaAnnottee.class,
+ * enumRef = JavaSimpleEnumeration.BAR
+ * )
+ * public class JavaAnnottee {}
+ * }}}
+ * {{{
+ * import scala.reflect.runtime.universe._
+ * import scala.reflect.runtime.{currentMirror => cm}
+ *
+ * object Test extends App {
+ * val jann = typeOf[JavaAnnottee].typeSymbol.annotations(0).javaArgs
+ * def jarg(name: String) = jann(newTermName(name)).asInstanceOf[LiteralArgument].value
+ *
+ * val classRef = jarg("classRef").typeValue
+ * println(showRaw(classRef)) // TypeRef(ThisType(<empty>), JavaAnnottee, List())
+ * println(cm.runtimeClass(classRef)) // class JavaAnnottee
+ *
+ * val enumRef = jarg("enumRef").symbolValue
+ * println(enumRef) // value BAR
+ *
+ * val siblings = enumRef.owner.typeSignature.declarations
+ * val enumValues = siblings.filter(sym => sym.isVal && sym.isPublic)
+ * println(enumValues) // Scope{
+ * // final val FOO: JavaSimpleEnumeration;
+ * // final val BAR: JavaSimpleEnumeration
+ * // }
+ *
+ * // doesn't work because of https://issues.scala-lang.org/browse/SI-6459
+ * // val enumValue = mirror.reflectField(enumRef.asTerm).get
+ * val enumClass = cm.runtimeClass(enumRef.owner.asClass)
+ * val enumValue = enumClass.getDeclaredField(enumRef.name.toString).get(null)
+ * println(enumValue) // BAR
+ * }
+ * }}}
*
* @contentDiagram hideNodes "*Api"
*/
diff --git a/src/reflect/scala/reflect/api/Exprs.scala b/src/reflect/scala/reflect/api/Exprs.scala
index 788fc889a8..45bfddb55d 100644
--- a/src/reflect/scala/reflect/api/Exprs.scala
+++ b/src/reflect/scala/reflect/api/Exprs.scala
@@ -8,8 +8,7 @@ package api
import scala.reflect.runtime.{universe => ru}
-/** A slice of [[scala.reflect.api.Universe the Scala reflection cake]] that defines strongly-typed tree wrappers and operations on them.
- * See [[scala.reflect.api.Universe]] for a description of how the reflection API is encoded with the cake pattern.
+/** A trait that defines strongly-typed tree wrappers and operations on them for use in Scala Reflection.
*
* `Expr` wraps an abstract syntax tree ([[scala.reflect.api.Trees#Tree]]) and tags it with its type ([[scala.reflect.api.Types#Type]]).
*
diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala
index 701442b632..a7d1ca05a6 100644
--- a/src/reflect/scala/reflect/api/FlagSets.scala
+++ b/src/reflect/scala/reflect/api/FlagSets.scala
@@ -3,32 +3,51 @@ package api
import scala.language.implicitConversions
-/** A slice of [[scala.reflect.api.Universe the Scala reflection cake]] that defines flag sets and operations on them.
- * See [[scala.reflect.api.Universe]] for a description of how the reflection API is encoded with the cake pattern.
+/**
+ * The trait that defines flag sets and operations on them.
*
- * Flags are used to provide modifiers for abstract syntax trees that represent definitions
- * via the `flags` field of [[scala.reflect.api.Trees#Modifiers]]. Trees that accept modifiers are:
- * [[scala.reflect.api.Trees#ClassDef]] (classes and traits), [[scala.reflect.api.Trees#ModuleDef]] (objects),
- * [[scala.reflect.api.Trees#ValDef]] (vals, vars, parameters and self-type annotations),
- * [[scala.reflect.api.Trees#DefDef]] (methods and constructors) and
- * [[scala.reflect.api.Trees#TypeDef]] (type aliases, abstract type members and type parameters).
+ * `Flag`s are used to provide modifiers for abstract syntax trees that represent definitions
+ * via the `flags` field of [[scala.reflect.api.Trees#Modifiers]]. Trees that accept modifiers are:
*
- * For example, to create a class named `C` one would write `ClassDef(Modifiers(NoFlags), newTypeName("C"), Nil, ...)`.
- * Here the flag set is empty, representing a vanilla class definition. To make `C` private, one would write
- * `ClassDef(Modifiers(PRIVATE), newTypeName("C"), Nil, ...)`. Flags can also be combined with the vertical bar operator (`|`).
- * For example, a private final class is written as followed: `ClassDef(Modifiers(PRIVATE | FINAL), newTypeName("C"), Nil, ...)`.
+ * - '''[[scala.reflect.api.Trees#ClassDef]]'''. Classes and traits.
+ * - '''[[scala.reflect.api.Trees#ModuleDef]]'''. Objects.
+ * - '''[[scala.reflect.api.Trees#ValDef]]'''. Vals, vars, parameters and self-type annotations.
+ * - '''[[scala.reflect.api.Trees#DefDef]]'''. Methods and constructors.
+ * - '''[[scala.reflect.api.Trees#TypeDef]]'''. Type aliases, abstract type members and type parameters.
*
- * The list of all available flags is defined in [[scala.reflect.api.FlagSets#FlagValues]], available via the [[scala.reflect.api.FlagSets#Flag]]
- * (typically one writes a blanket import for that, e.g. `import scala.reflect.runtime.universe.Flag._`).
+ * For example, to create a class named `C` one would write something like:
+ * {{{
+ * ClassDef(Modifiers(NoFlags), newTypeName("C"), Nil, ...)
+ * }}}
+ *
+ * Here, the flag set is empty.
*
- * Definition trees are compiled down to symbols, so flags on modifiers of such trees are transformed into flags on the resulting symbols.
- * Unlike trees, symbols don't expose flags, but rather provide `isXXX` test methods (e.g. `isFinal` can be used to test finality). These test methods
- * might require an upcast with `asTerm`, `asType` or `asClass` as some flags only make sense for certain flavors of symbols.
+ * To make `C` private, one would write something like:
+ * {{{
+ * ClassDef(Modifiers(PRIVATE), newTypeName("C"), Nil, ...)
+ * }}}
*
- * === Known issues ===
+ * Flags can also be combined with the vertical bar operator (`|`).
+ * For example, a private final class is written something like:
+ * {{{
+ * ClassDef(Modifiers(PRIVATE | FINAL), newTypeName("C"), Nil, ...)
+ * }}}
+ *
+ * The list of all available flags is defined in [[scala.reflect.api.FlagSets#FlagValues]], available via
+ * [[scala.reflect.api.FlagSets#Flag]]. (Typically one writes a blanket import for this, e.g.
+ * `import scala.reflect.runtime.universe.Flag._`).
+ *
+ * Definition trees are compiled down to symbols, so flags on modifiers of these trees are transformed into flags
+ * on the resulting symbols. Unlike trees, symbols don't expose flags, but rather provide `isXXX` test methods
+ * (e.g. `isFinal` can be used to test finality). These test methods might require an upcast with `asTerm`,
+ * `asType` or `asClass` as some flags only make sense for certain kinds of symbols.
+ *
+ * ''Of Note:'' This part of the Reflection API is being considered as a candidate for redesign. It is
+ * quite possible that in future releases of the reflection API, flag sets could be replaced with something else.
+ *
+ * For more details about `FlagSet`s and other aspects of Scala reflection, see the
+ * [[http://docs.scala-lang.org/overviews/reflection/overview.html Reflection Guide]]
*
- * This API is considered to be a candidate for redesign. It is quite probable that in future releases of the reflection API
- * flag sets will be replaced with something else.
*/
trait FlagSets { self: Universe =>
diff --git a/src/reflect/scala/reflect/api/Importers.scala b/src/reflect/scala/reflect/api/Importers.scala
index fde8794348..4286b2b45c 100644
--- a/src/reflect/scala/reflect/api/Importers.scala
+++ b/src/reflect/scala/reflect/api/Importers.scala
@@ -3,33 +3,23 @@ package api
/** This trait provides support for importers, a facility to migrate reflection artifacts between universes.
*
- * Reflection artifacts, such as symbols and types, are contained in universes. Typically all processing happens
- * within a single universe (e.g. a compile-time macro universe or a runtime reflection universe), but sometimes
- * there is a need to migrate artifacts from one universe to another. For example, runtime compilation works by
- * importing runtime reflection trees into a runtime compiler universe, compiling the importees and exporting the
+ * Reflection artifacts, such as [[scala.reflect.api.Symbols Symbols]] and [[scala.reflect.api.Types Types]],
+ * are contained in [[scala.reflect.api.Universes Universe]]s. Typically all processing happens
+ * within a single `Universe` (e.g. a compile-time macro `Universe` or a runtime reflection `Universe`), but sometimes
+ * there is a need to migrate artifacts from one `Universe` to another. For example, runtime compilation works by
+ * importing runtime reflection trees into a runtime compiler universe, compiling the importees and exporting the
* result back.
*
- * Reflection artifacts are firmly grounded in their universes, which is reflected by the fact that types of artifacts
- * from different universes are not compatible. By using importers, however, they be imported from one universe
- * into another. For example, to import `foo.bar.Baz` from the source universe to the target universe,
- * an importer will first check whether the entire owner chain exists in the target universe.
+ * Reflection artifacts are firmly grounded in their `Universe`s, which is reflected by the fact that types of artifacts
+ * from different universes are not compatible. By using `Importer`s, however, they be imported from one universe
+ * into another. For example, to import `foo.bar.Baz` from the source `Universe` to the target `Universe`,
+ * an importer will first check whether the entire owner chain exists in the target `Universe`.
* If it does, then nothing else will be done. Otherwise, the importer will recreate the entire owner chain
- * and will import the corresponding type signaturers into the target universe.
+ * and will import the corresponding type signatures into the target `Universe`.
*
- * Since importers match symbol tables of the source and the target universes using plain string names,
+ * Since importers match `Symbol` tables of the source and the target `Universe`s using plain string names,
* it is programmer's responsibility to make sure that imports don't distort semantics, e.g., that
- * `foo.bar.Baz` in the source universe means the same that `foo.bar.Baz` does in the target universe.
- *
- * === Known issues ===
- *
- * Importers didn't undergo as much testing as most of the reflection API did,
- * so they might be flaky from time to time. Please report issues if you encounter them.
- *
- * Importers are currently not mirror-aware, they always use `rootMirror`
- * of the target universe to resolve symbols. This might cause troubles in cases when the target universe
- * need a non-standard way of symbol resolution (e.g. a classloader that's different from the default one).
- * We have created [[https://issues.scala-lang.org/browse/SI-6241 https://issues.scala-lang.org/browse/SI-6241]],
- * an issue in the issue tracker, to track the implementation of this feature.
+ * `foo.bar.Baz` in the source `Universe` means the same that `foo.bar.Baz` does in the target `Universe`.
*
* === Example ===
*
diff --git a/src/reflect/scala/reflect/api/JavaMirrors.scala b/src/reflect/scala/reflect/api/JavaMirrors.scala
index 9bc888b884..df099006b5 100644
--- a/src/reflect/scala/reflect/api/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/api/JavaMirrors.scala
@@ -5,7 +5,12 @@ package api
*
* This refinement equips mirrors with reflection capabilities for the JVM. `JavaMirror` can
* convert Scala reflection artifacts (symbols and types) into Java reflection artifacts (classes)
- * and vice versa. It can also perform reflective invocations (getting/settings field values, calling methods, etc).
+ * and vice versa. It can also perform reflective invocations (getting/setting field values,
+ * calling methods, etc).
+ *
+ * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the
+ * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]]
+ *
* @groupname JavaMirrors Java Mirrors
*/
trait JavaMirrors { self: JavaUniverse =>
@@ -15,7 +20,7 @@ trait JavaMirrors { self: JavaUniverse =>
*/
type RuntimeClass = java.lang.Class[_]
- /** In runtime reflection universes, mirrors are JavaMirrors.
+ /** In runtime reflection universes, mirrors are `JavaMirrors`.
* @group JavaMirrors
*/
override type Mirror >: Null <: JavaMirror
@@ -23,10 +28,12 @@ trait JavaMirrors { self: JavaUniverse =>
/** A refinement of [[scala.reflect.api.Mirror]] for runtime reflection using JVM classloaders.
*
* With this upgrade, mirrors become capable of converting Scala reflection artifacts (symbols and types)
- * into Java reflection artifacts (classes) and vice versa. Consequently refined mirrors
- * become capable of performing reflective invocations (getting/settings field values, calling methods, etc).
+ * into Java reflection artifacts (classes) and vice versa. Consequently, refined mirrors
+ * become capable of performing reflective invocations (getting/setting field values, calling methods, etc).
+ *
+ * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the
+ * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]]
*
- * See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
* @group JavaMirrors
*/
trait JavaMirror extends scala.reflect.api.Mirror[self.type] with RuntimeMirror {
@@ -35,7 +42,10 @@ trait JavaMirrors { self: JavaUniverse =>
}
/** Creates a runtime reflection mirror from a JVM classloader.
- * See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
+ *
+ * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the
+ * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]]
+ *
* @group JavaMirrors
*/
def runtimeMirror(cl: ClassLoader): Mirror
diff --git a/src/reflect/scala/reflect/api/Mirror.scala b/src/reflect/scala/reflect/api/Mirror.scala
index 60ba087933..b1290cc02e 100644
--- a/src/reflect/scala/reflect/api/Mirror.scala
+++ b/src/reflect/scala/reflect/api/Mirror.scala
@@ -4,16 +4,15 @@ package api
/**
* The base class for all mirrors.
*
- * See the [[http://docs.scala-lang.org/overviews/reflection/overview.html Reflection Guide]] for a description of mirrors
- * and infomation on getting started with Scala reflection API.
- *
- * Note: Unlike most Scala reflection artifact classes, `Mirror` is not defined as an inner class,
- * so that it can be referenced from outside. For example, [[scala.reflect.api.TypeCreator]] and [[scala.reflect.api.TreeCreator]]
- * reference `Mirror` 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 [[scala.reflect.api.Mirrors]] or [[docs.scala-lang.org/overviews/reflection/overview.html Reflection Guide]]
+ * for a complete overview of `Mirror`s.
*
* @tparam U the type of the universe this mirror belongs to.
*/
+// Note: Unlike most Scala reflection artifact classes, `Mirror` is not defined as an inner class,
+// so that it can be referenced from outside. For example, [[scala.reflect.api.TypeCreator]] and [[scala.reflect.api.TreeCreator]]
+// reference `Mirror` 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.
abstract class Mirror[U <: Universe with Singleton] {
/** The universe this mirror belongs to.
* @group Mirror
diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala
index 32cfdf07fb..cc1b9762cb 100644
--- a/src/reflect/scala/reflect/api/Mirrors.scala
+++ b/src/reflect/scala/reflect/api/Mirrors.scala
@@ -1,10 +1,205 @@
package scala.reflect
package api
-/** This trait provides support for Mirrors in the reflection API.
+/** This trait provides support for Mirrors in the Scala Reflection API.
*
- * See the [[http://docs.scala-lang.org/overviews/reflection/overview.html Reflection Guide]] for a description of mirrors
- * and infomation on getting started with Scala reflection API.
+ * `Mirror`s are a central part of Scala Reflection. All information provided by
+ * reflection is made accessible through `Mirror`s. Depending on the type of information
+ * to be obtained, or the reflective action to be taken, different flavors of mirrors
+ * must be used. "Classloader" mirrors can be used to obtain representations of types
+ * and members. From a classloader `Mirror`, it's possible to obtain more specialized
+ * "invoker" `Mirror`s (the most commonly-used mirrors), which implement reflective
+ * invocations, such as method/constructor calls and field accesses.
+ *
+ * The two flavors of mirrors:
+ *
+ * <ul>
+ * <li>```“Classloader” mirrors```. These mirrors translate names to symbols
+ * (via methods `staticClass`/`staticModule`/`staticPackage`).</li>
+ * <li>```"Invoker” mirrors```. These mirrors implement reflective invocations
+ * (via methods `MethodMirror.apply`, `FieldMirror.get`, etc). These "invoker"
+ * mirrors are the types of mirrors that are most commonly used.</li>
+ * </ul>
+ *
+ * === Compile-time Mirrors ===
+ * Compile-time `Mirror`s make use of only classloader `Mirror`s to load `Symbol`s
+ * by name.
+ *
+ * The entry point to classloader `Mirror`s is via [[scala.reflect.macros.Context#mirror]].
+ * Typical methods which use classloader `Mirror`s include [[scala.reflect.api.Mirror#staticClass]],
+ * [[scala.reflect.api.Mirror#staticModule]], and [[scala.reflect.api.Mirror#staticPackage]]. For
+ * example:
+ * {{{
+ * import scala.reflect.macros.Context
+ *
+ * case class Location(filename: String, line: Int, column: Int)
+ *
+ * object Macros {
+ * def currentLocation: Location = macro impl
+ *
+ * def impl(c: Context): c.Expr[Location] = {
+ * import c.universe._
+ * val pos = c.macroApplication.pos
+ * val clsLocation = c.mirror.staticModule("Location") // get symbol of "Location" object
+ * c.Expr(Apply(Ident(clsLocation), List(Literal(Constant(pos.source.path)), Literal(Constant(pos.line)), Literal(Constant(pos.column)))))
+ * }
+ * }
+ * }}}
+ *
+ * ''Of Note:'' There are several high-level alternatives that one can use to avoid having to manually
+ * lookup symbols. For example, `typeOf[Location.type].termSymbol` (or `typeOf[Location].typeSymbol`
+ * if we needed a `ClassSymbol`), which are type safe since we don’t have to use `String`s to lookup
+ * the `Symbol`.
+ *
+ * === Runtime Mirrors ===
+ *
+ * Runtime `Mirror`s make use of both classloader and invoker `Mirror`s.
+ *
+ * The entry point to `Mirror`s for use at runtime is via `ru.runtimeMirror(<classloader>)`, where
+ * `ru` is [[scala.reflect.runtime.universe]].
+ *
+ * The result of a [[scala.reflect.api.JavaMirrors#runtimeMirror]] call is a classloader mirror,
+ * of type [[scala.reflect.api.Mirrors#ReflectiveMirror]], which can load symbols by names as
+ * discussed above (in the “Compile-time” section).
+ *
+ * A classloader mirror can create invoker mirrors, which include: [[scala.reflect.api.Mirrors#InstanceMirror]],
+ * [[scala.reflect.api.Mirrors#MethodMirror]], [[scala.reflect.api.Mirrors#FieldMirror]],
+ * [[scala.reflect.api.Mirrors#ClassMirror]] and [[scala.reflect.api.Mirrors#ModuleMirror]].
+ *
+ * Examples of how these two types of `Mirror`s interact are available below.
+ *
+ * === Types of Mirrors, Their Use Cases & Examples ===
+ *
+ * '''[[scala.reflect.api.Mirrors#ReflectiveMirror]]'''. Used for loading `Symbol`s by name, and
+ * as an entry point into invoker mirrors. Entry point: `val m = ru.runtimeMirror(<classloader>)`.
+ * Example:
+ * {{{
+ * scala> val ru = scala.reflect.runtime.universe
+ * ru: scala.reflect.api.JavaUniverse = ...
+ *
+ * scala> val m = ru.runtimeMirror(getClass.getClassLoader)
+ * m: reflect.runtime.universe.Mirror = JavaMirror ...
+ * }}}
+ *
+ * '''[[scala.reflect.api.Mirrors#InstanceMirror]]'''. Used for creating invoker `Mirror`s for methods
+ * and fields and for inner classes and inner objects (modules). Entry point: `val im = m.reflect(<value>)`.
+ * Example:
+ * {{{
+ * scala> class C { def x = 2 }
+ * defined class C
+ *
+ * scala> val im = m.reflect(new C)
+ * im: reflect.runtime.universe.InstanceMirror = instance mirror for C@3442299e
+ * }}}
+ *
+ * '''[[scala.reflect.api.Mirrors#MethodMirror]]'''. Used for invoking instance methods (Scala only has
+ * instance methods-- methods of objects are instance methods of object instances, obtainable
+ * via `ModuleMirror.instance`). Entry point: `val mm = im.reflectMethod(<method symbol>)`.
+ * Example:
+ * {{{
+ * scala> val methodX = typeOf[C].declaration(newTermName("x")).asMethod
+ * methodX: reflect.runtime.universe.MethodSymbol = method x
+ *
+ * scala> val mm = im.reflectMethod(methodX)
+ * mm: reflect.runtime.universe.MethodMirror = method mirror for C.x: scala.Int (bound to C@3442299e)
+ *
+ * scala> mm()
+ * res0: Any = 2
+ * }}}
+ *
+ * '''[[scala.reflect.api.Mirrors#FieldMirror]]'''. Used for getting/setting instance fields
+ * (Scala only has instance fields-- fields of objects are instance methods of object instances
+ * obtainable via ModuleMirror.instance). Entry point:
+ * `val fm = im.reflectMethod(<field or accessor symbol>)`.
+ * Example:
+ * {{{
+ * scala> class C { val x = 2; val y = 3 }
+ * defined class C
+ *
+ * scala> val m = ru.runtimeMirror(getClass.getClassLoader)
+ * m: reflect.runtime.universe.Mirror = JavaMirror ...
+ *
+ * scala> val im = m.reflect(new C)
+ * im: reflect.runtime.universe.InstanceMirror = instance mirror for C@5f0c8ac1
+ *
+ * scala> val fieldX = typeOf[C].declaration(newTermName("x")).asTerm.accessed.asTerm
+ * fieldX: reflect.runtime.universe.TermSymbol = value x
+ * scala> val fmX = im.reflectField(fieldX)
+ * fmX: reflect.runtime.universe.FieldMirror = field mirror for C.x (bound to C@5f0c8ac1)
+ *
+ * scala> fmX.get
+ * res0: Any = 2
+ *
+ * scala> fmX.set(3)
+ * scala.ScalaReflectionException: cannot set an immutable field x
+ * ...
+ *
+ * scala> val fieldY = typeOf[C].declaration(newTermName("y")).asTerm.accessed.asTerm
+ * fieldY: reflect.runtime.universe.TermSymbol = variable y
+ *
+ * scala> val fmY = im.reflectField(fieldY)
+ * fmY: reflect.runtime.universe.FieldMirror = field mirror for C.y (bound to C@5f0c8ac1)
+ *
+ * scala> fmY.get
+ * res1: Any = 3
+ *
+ * scala> fmY.set(4)
+ *
+ * scala> fmY.get
+ * res2: Any = 4
+ * }}}
+ *
+ * '''[[scala.reflect.api.Mirrors#ClassMirror]]'''. Used for creating invoker mirrors for constructors.
+ * Entry points: for ''static classes'' `val cm1 = m.reflectClass(<class symbol>)`,
+ * for ''inner classes'' `val mm2 = im.reflectClass(<module symbol>)`.
+ * Example:
+ * {{{
+ * scala> case class C(x: Int)
+ * defined class C
+ *
+ * scala> val m = ru.runtimeMirror(getClass.getClassLoader)
+ * m: reflect.runtime.universe.Mirror = JavaMirror ...
+ *
+ * scala> val classC = typeOf[C].typeSymbol.asClass
+ *
+ * classC: reflect.runtime.universe.Symbol = class C
+ *
+ * scala> val cm = m.reflectClass(classC)
+ * cm: reflect.runtime.universe.ClassMirror = class mirror for C (bound to null)
+ *
+ * scala> val ctorC = typeOf[C].declaration(ru.nme.CONSTRUCTOR).asMethod
+ * ctorC: reflect.runtime.universe.MethodSymbol = constructor C
+ *
+ * scala> val ctorm = cm.reflectConstructor(ctorC)
+ * ctorm: reflect.runtime.universe.MethodMirror = constructor mirror for C.<init>(x: scala.Int): C (bound to null)
+ *
+ * scala> ctorm(2)
+ * res0: Any = C(2)
+ * }}}
+ *
+ * '''[[scala.reflect.api.Mirrors#ModuleMirror]]'''. Used for getting singleton instances of objects.
+ * Entry points: for ''static objects (modules)'' `val mm1 = m.reflectModule(<module symbol>)`,
+ * for ''inner objects (modules)'' `val mm2 = im.reflectModule(<module symbol>)`.
+ * Example:
+ * {{{
+ * scala> object C { def x = 2 }
+ * defined module C
+ *
+ * scala> val m = ru.runtimeMirror(getClass.getClassLoader)
+ * m: reflect.runtime.universe.Mirror = JavaMirror ...
+ *
+ * scala> val objectC = typeOf[C.type].termSymbol.asModule
+ * objectC: reflect.runtime.universe.ModuleSymbol = object C
+ *
+ * scala> val mm = m.reflectModule(objectC)
+ * mm: reflect.runtime.universe.ModuleMirror = module mirror for C (bound to null)
+ *
+ * scala> val obj = mm.instance
+ * obj: Any = C$@1005ec04
+ * }}}
+ *
+ * For more information about `Mirrors`s, see the
+ * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]]
*
* @contentDiagram hideNodes "*Api"
*/
diff --git a/src/reflect/scala/reflect/api/Names.scala b/src/reflect/scala/reflect/api/Names.scala
index 332c24e542..02eb79f8ed 100644
--- a/src/reflect/scala/reflect/api/Names.scala
+++ b/src/reflect/scala/reflect/api/Names.scala
@@ -5,7 +5,7 @@ package api
*
* Names are simple wrappers for strings. [[scala.reflect.api.Names#Name Name]] has two subtypes [[scala.reflect.api.Names#TermName TermName]] and [[scala.reflect.api.Names#TypeName TypeName]] which
* distinguish names of terms (like objects or members) and types. A term and a type of the
- * same name can co-exist in an object.
+ * same name can co-exist in an object.
*
* === Examples ===
*
@@ -13,7 +13,7 @@ package api
* use `typeOf[List[_]].member(newTermName("map"))`. To search for a type member, use
* newTypeName instead.
*
- * @see [[http://docs.scala-lang.org/overviews/reflection/overview.html]].
+ * See the [[docs.scala-lang.org/overviews/reflection/overview.html Reflection Guide]] for more about Scala Reflection.
*
* @contentDiagram hideNodes "*Api"
*/
diff --git a/src/reflect/scala/reflect/api/Position.scala b/src/reflect/scala/reflect/api/Position.scala
index fb199bbd69..61d643b449 100644
--- a/src/reflect/scala/reflect/api/Position.scala
+++ b/src/reflect/scala/reflect/api/Position.scala
@@ -16,6 +16,30 @@ import scala.reflect.macros.Attachments
* The compiler adds more information to positions, such a ranges in the source file and defines different types of
* positions depending on how a symbol or tree node was generated. The guide fully describes compiler-generated positions.
*
+ * - INV1: A tree with an offset position never contains a child
+ * with a range position
+ * - INV2: If the child of a tree with a range position also has a range position,
+ * then the child's range is contained in the parent's range.
+ * - INV3: Opaque range positions of children of the same node are non-overlapping
+ * (this means their overlap is at most a single point).
+ *
+ * The following tests are useful on positions:
+ * `pos.isDefined` true if position is not a NoPosition,
+ * `pos.isRange` true if position is a range,
+ * `pos.isOpaqueRange` true if position is an opaque range,
+ *
+ * There are also convenience methods, such as
+ * `pos.startOrPoint`,
+ * `pos.endOrPoint`,
+ * `pos.pointOrElse(default)`.
+ * These are less strict about the kind of position on which they can be applied.
+ *
+ * The following conversion methods are often used:
+ * `pos.focus` converts a range position to an offset position, keeping its point;
+ * returns all other positions unchanged,
+ * `pos.makeTransparent` converts an opaque range position into a transparent one.
+ * returns all other positions unchanged.
+ *
* @groupname Common Commonly used methods
*/
trait Position extends Attachments {
diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala
index b7157af153..1e8161aeef 100644
--- a/src/reflect/scala/reflect/api/Printers.scala
+++ b/src/reflect/scala/reflect/api/Printers.scala
@@ -3,9 +3,12 @@ package api
import java.io.{ PrintWriter, StringWriter }
-/** A slice of [[scala.reflect.api.Universe the Scala reflection cake]] that defines prettyprinting functionality.
+/** Utilities for nicely printing [[scala.reflect.api.Trees]] and [[scala.reflect.api.Types]].
*
- * === Examples (trees) ===
+ * === Printing Trees ===
+ * The method `show` displays the "prettified" representation of reflection artifacts.
+ * This representation provides one with the desugared Java representation of Scala code.
+ * For example:
*
* {{{
* scala> import scala.reflect.runtime.universe._
@@ -14,9 +17,6 @@ import java.io.{ PrintWriter, StringWriter }
* scala> def tree = reify{ final class C { def x = 2 } }.tree
* tree: reflect.runtime.universe.Tree
*
- * // show displays prettified representation of reflection artifacts
- * // which is typically close to Scala code, but sometimes not quite
- * // (e.g. here the constructor is shown in a desugared way)
* scala> show(tree)
* res0: String =
* {
@@ -29,21 +29,17 @@ import java.io.{ PrintWriter, StringWriter }
* };
* ()
* }
+ * }}}
+ *
+ * The method `showRaw` displays internal structure of a given reflection object
+ * as a Scala abstract syntax tree (AST), the representation that the Scala typechecker
+ * operates on.
*
- * // showRaw displays internal structure of a given reflection object
- * // trees and types (type examples are shown below) are case classes
- * // so they are shown in a form that's almost copy/pasteable
- * //
- * // almost copy/pasteable, but not completely - that's because of symbols
- * // there's no good way to get a roundtrip-surviving representation of symbols
- * // in general case, therefore only symbol names are shown (e.g. take a look at AnyRef)
- * //
- * // in such a representation, it's impossible to distinguish Idents/Selects
- * // that have underlying symbols vs ones that don't have symbols, because in both cases
- * // only names will be printed
- * //
- * // to overcome this limitation, use `printIds` and `printKinds` - optional parameters
- * // of the `showRaw` method (an example is shown below)
+ * Note, that while this representation appears to generate correct trees that one
+ * might think would be possible to use in a macro implementation, this is not usually
+ * the case. Symbols aren't fully represented (only their names are). Thus, this method
+ * is best-suited for use simply inspecting ASTs given some valid Scala code.
+ * {{{
* scala> showRaw(tree)
* res1: String = Block(List(
* ClassDef(Modifiers(FINAL), newTypeName("C"), List(), Template(
@@ -57,15 +53,17 @@ import java.io.{ PrintWriter, StringWriter }
* DefDef(Modifiers(), newTermName("x"), List(), List(), TypeTree(),
* Literal(Constant(2))))))),
* Literal(Constant(())))
- *
+ * }}}
+ *
+ * The method `showRaw` can also print [[scala.reflect.api.Types]] next to the artifacts
+ * being inspected
+ * {{{
* scala> import scala.tools.reflect.ToolBox // requires scala-compiler.jar
* import scala.tools.reflect.ToolBox
*
* scala> import scala.reflect.runtime.{currentMirror => cm}
* import scala.reflect.runtime.{currentMirror=>cm}
*
- * // showRaw can also print types next to the artifacts being inspected
- * // provide true for a `printTypes` arguments to achieve this effect
* scala> showRaw(cm.mkToolBox().typeCheck(tree), printTypes = true)
* res2: String = Block[1](List(
* ClassDef[2](Modifiers(FINAL), newTypeName("C"), List(), Template[3](
@@ -89,8 +87,9 @@ import java.io.{ PrintWriter, StringWriter }
* [8] ConstantType(Constant(2))
* }}}
*
- * === Examples (types) ===
+ * === Printing Types ===
*
+ * The method `show`
* {{{
* scala> import scala.reflect.runtime.universe._
* import scala.reflect.runtime.universe._
@@ -98,10 +97,14 @@ import java.io.{ PrintWriter, StringWriter }
* scala> def tpe = typeOf[{ def x: Int; val y: List[Int] }]
* tpe: reflect.runtime.universe.Type
*
- * // show has already been discussed above
* scala> show(tpe)
* res0: String = scala.AnyRef{def x: Int; val y: scala.List[Int]}
+ * }}}
*
+ * Like the method `showRaw` for [[scala.reflect.api.Trees]], `showRaw`
+ * for [[scala.reflect.api.Types]] provides a visualization of the Scala
+ * AST operated on by the Scala typechecker.
+ * {{{
* // showRaw has already been discussed above
* scala> showRaw(tpe)
* res1: String = RefinedType(
@@ -109,18 +112,10 @@ import java.io.{ PrintWriter, StringWriter }
* Scope(
* newTermName("x"),
* newTermName("y")))
+ * }}}
*
- * // when `printIds` and/or `printKinds` arguments are provided for showRaw
- * // the prettyprinter reveals underlying symbols and their flavors
- * //
- * // courtesy of `printKinds` we can see four different symbols: a package class `scala`,
- * // a type alias `AnyRef`, a method named `x` and a getter named `y`.
- * //
- * // thanks to `printIds` we can see unique identifiers of symbols
- * // so that it becomes possible to distinguish, say, `scala.collection.immutable.List`
- * // from `scala.collection.mutable.List` (this also helps in rare cases
- * // when the same reflection entity is represented by multiple symbols, but let's
- * // not speak of these horrors here)
+ * `printIds` and/or `printKinds` can additionally be supplied as arguments in a call to
+ * `showRaw` which additionally shows the unique identifiers of symbols.
* scala> showRaw(tpe, printIds = true, printKinds = true)
* res2: String = RefinedType(
* List(TypeRef(ThisType(scala#2043#PK), newTypeName("AnyRef")#691#TPE, List())),
@@ -128,6 +123,10 @@ import java.io.{ PrintWriter, StringWriter }
* newTermName("x")#2540#METH,
* newTermName("y")#2541#GET))
* }}}
+ *
+ * For more details about `Printer`s and other aspects of Scala reflection, see the
+ * [[http://docs.scala-lang.org/overviews/reflection/overview.html Reflection Guide]]
+ *
*/
trait Printers { self: Universe =>
@@ -176,8 +175,9 @@ trait Printers { self: Universe =>
*/
override protected def treeToString(tree: Tree) = show(tree)
- /** Renders a prettified representation of a reflection artifact.
- * Typically it looks very close to the Scala code it represents.
+ /** Renders a representation of a reflection artifact
+ * as desugared Java code.
+ *
* @group Printers
*/
def show(any: Any, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printKinds: BooleanFlag = None, printMirrors: BooleanFlag = None): String =
@@ -188,7 +188,9 @@ trait Printers { self: Universe =>
*/
protected def newTreePrinter(out: PrintWriter): TreePrinter
- /** Renders internal structure of a reflection artifact.
+ /** Renders internal structure of a reflection artifact as the
+ * visualization of a Scala syntax tree.
+ *
* @group Printers
*/
def showRaw(any: Any, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printKinds: BooleanFlag = None, printMirrors: BooleanFlag = None): String =
diff --git a/src/reflect/scala/reflect/api/StandardDefinitions.scala b/src/reflect/scala/reflect/api/StandardDefinitions.scala
index e1eadde3ad..a31a501357 100644
--- a/src/reflect/scala/reflect/api/StandardDefinitions.scala
+++ b/src/reflect/scala/reflect/api/StandardDefinitions.scala
@@ -5,10 +5,11 @@
package scala.reflect
package api
-/** A slice of [[scala.reflect.api.Universe the Scala reflection cake]] that defines standard symbols and types.
+/** All Scala standard symbols and types.
*
- * These standard reflection artifacts can be referred to using `definitions` (typically imported with
- * a blanket import `import definitions._`) and are listed in [[scala.reflect.api.StandardDefinitions#DefinitionsApi]].
+ * These standard definitions can accessed to using `definitions`.
+ * They're typically imported with a blanket import `import definitions`, and are
+ * listed in [[scala.reflect.api.StandardDefinitions#DefinitionsApi]].
*/
trait StandardDefinitions {
self: Universe =>
diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala
index 203bcdbdc4..fc18c02706 100644
--- a/src/reflect/scala/reflect/api/StandardNames.scala
+++ b/src/reflect/scala/reflect/api/StandardNames.scala
@@ -10,8 +10,7 @@ package api
// 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.
-/** This trait is the [[scala.reflect.api.Universe reflection API]] component that defines standard [[Names names used in reflection and macros]].
- *
+/**
* Standard names are names that are essential to creating trees or to reflecting Scala artifacts.
* For example, `CONSTRUCTOR` (aka `<init>` on JVM) is necessary to create and invoke constructors.
*
diff --git a/src/reflect/scala/reflect/api/TreeCreator.scala b/src/reflect/scala/reflect/api/TreeCreator.scala
index c668fe0b4d..cba90b72e6 100644
--- a/src/reflect/scala/reflect/api/TreeCreator.scala
+++ b/src/reflect/scala/reflect/api/TreeCreator.scala
@@ -3,7 +3,7 @@ package api
/** This is an internal implementation class.
*
- * @see [[http://docs.scala-lang.org/overviews/reflection/architecture.html]].
+ * This class is used internally by Scala Reflection, and is not recommended for use in client code.
*/
abstract class TreeCreator {
def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Tree
diff --git a/src/reflect/scala/reflect/api/TypeCreator.scala b/src/reflect/scala/reflect/api/TypeCreator.scala
index 16585cd23f..9c386f2939 100644
--- a/src/reflect/scala/reflect/api/TypeCreator.scala
+++ b/src/reflect/scala/reflect/api/TypeCreator.scala
@@ -1,9 +1,9 @@
package scala.reflect
package api
-/** This is an internal implementation class.
- *
- * @see [[http://docs.scala-lang.org/overviews/reflection/architecture.html]].
+/** A mirror-aware factory for types.
+ *
+ * This class is used internally by Scala Reflection, and is not recommended for use in client code.
*/
abstract class TypeCreator {
def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Type
diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala
index 9d66a9e236..812d5199fc 100644
--- a/src/reflect/scala/reflect/api/TypeTags.scala
+++ b/src/reflect/scala/reflect/api/TypeTags.scala
@@ -17,130 +17,143 @@ import scala.language.implicitConversions
* [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 slice of [[scala.reflect.api.Universe the Scala reflection cake]] that defines type tags and operations on them.
- * See [[scala.reflect.api.Universe]] for a description of how the reflection API is encoded with the cake pattern.
- *
- * 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]].
- *
- * 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:
+/**
+ * A `TypeTag[T]` encapsulates the runtime type representation of some type `T`.
+ * Like [[scala.reflect.Manifest]], the prime use case of `TypeTag`s is to give access
+ * to erased types. However, `TypeTag`s should be considered to be a richer
+ * replacement of the pre-2.10 notion of a [[scala.reflect.Manifest Manifest]], that
+ * are, in addition, fully integrated with Scala reflection.
*
+ * There exist three different types of `TypeTags`:
+ *
+ * <ul>
+ * <li>[[scala.reflect.api.TypeTags#TypeTag]]. <br/>A full type descriptor of a Scala type.
+ * For example, a `TypeTag[List[String]]` contains all type information,
+ * in this case, of type `scala.List[String]`.</li>
+ *
+ * <li>[[scala.reflect.ClassTag]]. <br/>A partial type descriptor of a Scala type. For
+ * example, a `ClassTag[List[String]]` contains only the erased class
+ * type information, in this case, of type `scala.collection.immutable.List`.
+ * `ClassTag`s provide access only to the runtime class of a type.
+ * Analogous to [[scala.reflect.ClassManifest]]</li>
+ *
+ * <li>[[scala.reflect.api.TypeTags#WeakTypeTag]]. <br/>A type descriptor for abstract
+ * types (see description below).</li>
+ * </ul>
+ *
+ * Like [[scala.reflect.Manifest Manifest]]s, `TypeTag`s are always generated by the
+ * compiler, and can be obtained in three ways:
+ *
+ * === #1 Via the methods [[scala.reflect.api.TypeTags#typeTag typeTag]],
+ * [[scala.reflect#classTag classTag]], or [[scala.reflect.api.TypeTags#weakTypeTag weakTypeTag]] ===
+ *
+ * For example:
* {{{
- * 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)
+ * import scala.reflect.runtime.universe._
+ * val tt = typeTag[Int]
+ *
+ * import scala.reflect._
+ * val ct = classTag[String]
+ * }}}
+ *
+ * Each of these methods constructs a `TypeTag[T]` or `ClassTag[T]` for the given
+ * type argument `T`.
+ *
+ * === #2 Using an implicit parameter of type `TypeTag[T]`, `ClassTag[T]`, or `WeakTypeTag[T]
+ *
+ * For example:
+ * {{{
+ * import scala.reflect.runtime.universe._
+ *
+ * def paramInfo[T](x: T)(implicit tag: TypeTag[T]): Unit = {
+ * val targs = tag.tpe match { case TypeRef(_, _, args) => args }
+ * println(s"type of $x has type arguments $targs")
* }
+ *
+ * scala> paramInfo(42)
+ * type of 42 has type arguments List()
+ *
+ * scala> paramInfo(List(1, 2))
+ * type of List(1, 2) has type arguments List(Int)
* }}}
*
- * 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.
+ * === #3 Context bound of a type parameter ===
*
- * 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.
+ * ...on methods or classes. The above example can be implemented as follows:
*
- * === Backward compatibility with Manifests ===
+ * {{{
+ * import scala.reflect.runtime.universe._
+ *
+ * def paramInfo[T: TypeTag](x: T): Unit = {
+ * val targs = typeOf[T] match { case TypeRef(_, _, args) => args }
+ * println(s"type of $x has type arguments $targs")
+ * }
+ *
+ * scala> paramInfo(42)
+ * type of 42 has type arguments List()
*
- * Type tags correspond loosely to manifests.
+ * scala> paramInfo(List(1, 2))
+ * type of List(1, 2) has type arguments List(Int)
+ * }}}
+ *
+ * === `WeakTypeTag`s ===
+ *
+ *`WeakTypeTag[T]` generalizes `TypeTag[T]`. Unlike a regular `TypeTag`, components of
+ * its type representation can be references to type parameters or abstract types.
+ * However, `WeakTypeTag[T]` tries 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[T]`.
*
- * 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,
+ * Continuing the example above:
+ * {{{
+ * def weakParamInfo[T](x: T)(implicit tag: WeakTypeTag[T]): Unit = {
+ * val targs = tag.tpe match { case TypeRef(_, _, args) => args }
+ * println(s"type of $x has type arguments $targs")
+ * }
*
- * In Scala 2.10 class manifests are deprecated, and manifests are planned to be deprecated in one of the
- * subsequent point releases. Therefore it's advisable to migrate manifests to tags.
+ * scala> def foo[T] = weakParamInfo(List[T]())
+ * foo: [T]=> Unit
*
- * In most cases it is enough to replace `ClassManifest` with `ClassTag` and `Manifest` with `TypeTag`.
- * There are however a few caveats:
+ * scala> foo[Int]
+ * type of List() has type arguments List(T)
+ * }}}
*
- * 1) Tags don't support the notion of `OptManifest`. Tags can reify arbitrary types, so they are always available.
+ * === TypeTags and Manifests ===
*
- * 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`.
+ * `TypeTag`s correspond loosely to the pre-2.10 notion of
+ * [[scala.reflect.Manifest]]s. While [[scala.reflect.ClassTag]] corresponds to
+ * [[scala.reflect.ClassManifest]] and [[scala.reflect.api.TypeTags#TypeTag]] mostly
+ * corresponds to [[scala.reflect.Manifest]], other pre-2.10 `Manifest` types do not
+ * have a direct correspondence with a 2.10 "`Tag`" type.
*
- * 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).
+ * <ul>
+ * <li>'''[[scala.reflect.OptManifest]] is not supported.''' <br/>This is because `Tag`s
+ * can reify arbitrary types, so they are always available.<li>
*
- * 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.
+ * <li>'''There is no equivalent for [[scala.reflect.AnyValManifest]].''' <br/>Instead, one
+ * can compare their `Tag` with one of the base `Tag`s (defined in the corresponding
+ * companion objects) in order to find out whether or not it represents a primitive
+ * value class. Additionally, it's possible to simply use
+ * `<tag>.tpe.typeSymbol.isPrimitiveValueClass`.</li>
*
- * === Known issues ===
+ * <li>'''There are no replacement for factory methods defined in the `Manifest`
+ * companion objects'''. <br/>Instead, one could generate corresponding types using the
+ * reflection APIs provided by Java (for classes) and Scala (for types).</li>
*
- * Type tags are marked as serializable, but this functionality is not yet implemented.
- * An issue tracker entry: [[https://issues.scala-lang.org/browse/SI-5919 https://issues.scala-lang.org/browse/SI-5919]]
- * has been created to track the implementation of this feature.
+ * <li>'''Certain manifest operations(i.e., <:<, >:> and typeArguments) are not
+ * supported.''' <br/>Instead, one culd use the reflection APIs provided by Java (for
+ * classes) and Scala (for types).</li>
+ *</ul>
*
- * @see [[scala.reflect.ClassTag]], [[scala.reflect.api.Universe#TypeTag]], [[scala.reflect.api.Universe#WeakTypeTag]]
+ * In Scala 2.10, [[scala.reflect.ClassManifest]]s are deprecated, and it is planned
+ * to deprecate [[scala.reflect.Manifest]] in favor of `TypeTag`s and `ClassTag`s in
+ * an upcoming point release. Thus, it is advisable to migrate any `Manifest`-based
+ * APIs to use `Tag`s.
+ *
+ * For more information about `TypeTag`s, see the
+ * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]]
+ *
+ * @see [[scala.reflect.ClassTag]], [[scala.reflect.api.TypeTags#TypeTag]], [[scala.reflect.api.TypeTags#WeakTypeTag]]
* @group TypeTags Type Tags
*/
trait TypeTags { self: Universe =>
@@ -148,14 +161,17 @@ 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.
+ * If an implicit value of type `WeakTypeTag[T]` is required, the compiler will create one,
+ * and the reflective representation of `T` can be accessed via the `tpe` field.
+ * Components of `T` can be references to type parameters or abstract types. Note that `WeakTypeTag`
+ * makes an effort to be as concrete as possible, i.e. if `TypeTag`s 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 perhaps be partially
+ * abstract, but requires special care to handle this case. However, if `T` is expected to be fully known, use
+ * [[scala.reflect.api.TypeTags#TypeTag]] instead, which statically guarantees this property.
+ *
+ * For more information about `TypeTag`s, see the
+ * [[http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html Reflection Guide: TypeTags]]
*
* @see [[scala.reflect.api.TypeTags]]
* @group TypeTags
@@ -163,7 +179,7 @@ trait TypeTags { self: Universe =>
@annotation.implicitNotFound(msg = "No WeakTypeTag available for ${T}")
trait WeakTypeTag[T] extends Equals with Serializable {
/**
- * Underlying mirror of this type tag.
+ * The underlying `Mirror` of this type tag.
*/
val mirror: Mirror
@@ -180,16 +196,16 @@ trait TypeTags { self: Universe =>
*/
def tpe: Type
- /** TODO how do I doc this? */
+ // TODO how do I doc this?
override def canEqual(x: Any) = x.isInstanceOf[WeakTypeTag[_]]
- /** TODO how do I doc this? */
+ // TODO how do I doc this?
override def equals(x: Any) = x.isInstanceOf[WeakTypeTag[_]] && this.mirror == x.asInstanceOf[WeakTypeTag[_]].mirror && this.tpe == x.asInstanceOf[WeakTypeTag[_]].tpe
- /** TODO how do I doc this? */
+ // TODO how do I doc this?
override def hashCode = mirror.hashCode * 31 + tpe.hashCode
- /** TODO how do I doc this? */
+ // TODO how do I doc this?
override def toString = "WeakTypeTag[" + tpe + "]"
}
@@ -249,7 +265,7 @@ trait TypeTags { self: Universe =>
}
/**
- * A `TypeTag` is a [[scala.reflect.api.Universe#WeakTypeTag]] with the additional
+ * A `TypeTag` is a [[scala.reflect.api.TypeTags#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.
*
diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala
index d9be73fde9..7d1f5c9df1 100644
--- a/src/reflect/scala/reflect/api/Universe.scala
+++ b/src/reflect/scala/reflect/api/Universe.scala
@@ -2,13 +2,18 @@ package scala.reflect
package api
/**
- * The Scala reflection cake.
+ * `Universe` provides a complete set of reflection operations which make it possible for one
+ * to reflectively inspect Scala type relations, such as membership or subtyping.
*
- * See [[scala.reflect.api.package the overview page]] for a description of universes and infomation on getting started with Scala reflection API.
- * This page lists the most important layers of the cake, and describes paculiarities of cake APIs.
+ * [[scala.reflect.api.Universe]] has two specialized sub-universes for different scenarios.
+ * [[scala.reflect.api.JavaUniverse]] adds operations that link symbols and types to the underlying
+ * classes and runtime values of a JVM instance-- this can be thought of as the `Universe` that
+ * should be used for all typical use-cases of Scala reflection. [[scala.reflect.macros.Universe]]
+ * adds operations which allow macros to access selected compiler data structures and operations--
+ * this type of `Universe` should only ever exist within the implementation of a Scala macro.
*
- * 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:
+ * `Universe` can be thought of as the entry point to Scala reflection. It mixes-in, and thus provides
+ * an interface to the following main types:
*
* - [[scala.reflect.api.Types#Type Types]] represent types
* - [[scala.reflect.api.Symbols#Symbol Symbols]] represent definitions
@@ -19,58 +24,32 @@ package api
* - [[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.
+ *
+ * To obtain a `Universe` to use with Scala runtime reflection, simply make sure to use or import
+ * `scala.reflect.runtime.universe._`
+ * {{{
+ * scala> import scala.reflect.runtime.universe._
+ * import scala.reflect.runtime.universe._
+ *
+ * scala> typeOf[List[Int]]
+ * res0: reflect.runtime.universe.Type = scala.List[Int]
+ *
+ * scala> typeOf[Either[String, Int]]
+ * res1: reflect.runtime.universe.Type = scala.Either[String,Int]
+ * }}}
*
- * 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.macros]] 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.
- *
+ * To obtain a `Universe` for use within a Scala macro, use [[scala.reflect.macros.Context#universe]]. For example:
* {{{
- * 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)
+ * def printf(format: String, params: Any*): Unit = macro impl
+ * def impl(c: Context)(format: c.Expr[String], params: c.Expr[Any]*): c.Expr[Unit] = {
+ * import c.universe._
+ * ...
+ * }
* }}}
*
- * is equivalent to
- *
- * {{{
- * import scala.reflect.runtime.universe._
- * val iftree = reify{ if( condition ) 1 else 2 }.tree
- * }}}
+ * For more information about `Universe`s, see the [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Universes]]
*
- * 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`.
- * @groupprio Universe -1
+ * @groupprio Universe -1
*
* @contentDiagram hideNodes "*Api"
*/
@@ -93,9 +72,9 @@ abstract class Universe extends Symbols
with Printers
with Importers
{
- /** Produce the abstract syntax tree representing the given Scala expression.
+ /** Use `refiy` to produce the abstract syntax tree representing a given Scala expression.
*
- * For example
+ * For example:
*
* {{{
* val five = reify{ 5 } // Literal(Constant(5))
@@ -105,49 +84,7 @@ abstract class Universe extends Symbols
*
* 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
+ * 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.
* @group Universe
*/
// implementation is hardwired to `scala.reflect.reify.Taggers`
diff --git a/src/reflect/scala/reflect/api/package.scala b/src/reflect/scala/reflect/api/package.scala
index 449b7d5ce1..bd9c72a839 100644
--- a/src/reflect/scala/reflect/api/package.scala
+++ b/src/reflect/scala/reflect/api/package.scala
@@ -2,13 +2,22 @@ package scala.reflect
import scala.reflect.api.{Universe => ApiUniverse}
-/** The Scala reflection API (located at scala-reflect.jar).
+/** The Scala Reflection API (located in scala-reflect.jar).
*
- * Using Scala reflection requires understanding of a couple of basic concepts like [[Symbols Symbols]], [[Types Types]], [[Mirror Mirrors]] and [[Universe Universes]].
- * @see [[http://docs.scala-lang.org/overviews/reflection/overview.html]].
+ * In Scala 2.10.0, the Scala Reflection API and its implementation have an "experimental" status.
+ * This means that the API and the docs are not complete and can be changed in binary- and source-incompatible
+ * manner in 2.10.1. This also means that the implementation has some known issues.
*
- * In Scala 2.10.0, reflection API and its implementation have experimental status. This means that the API and the docs are not complete and can be changed
- * in binary- and source-incompatible manner in 2.10.1. This also means that the implementation has known issues
+ * The following types are the backbone of the Scala Reflection API, and serve as a good starting point
+ * for information about Scala Reflection:
+ *
+ * - [[scala.reflect.api.Symbols]]
+ * - [[scala.reflect.api.Types]]
+ * - [[scala.reflect.api.Mirrors]]
+ * - [[scala.reflect.api.Universe]]
+ *
+ * For more information about Scala Reflection, see the
+ * [[http://docs.scala-lang.org/overviews/reflection/overview.html Reflection Guide]]
*
* @groupprio API 9
* @groupprio Extractors 10
diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala
index b3f9ba5817..b97913daf0 100644
--- a/src/reflect/scala/reflect/runtime/package.scala
+++ b/src/reflect/scala/reflect/runtime/package.scala
@@ -5,14 +5,18 @@ package scala.reflect
*/
package object runtime {
- /** The entry point into runtime reflection.
- * See [[scala.reflect.api.package the overview page]] for details on how to use it.
+ /** The entry point into Scala runtime reflection.
+ *
+ * To use Scala runtime reflection, simply use or import `scala.reflect.runtime.universe._`
+ *
+ * See [[scala.reflect.api.Universe]] or the
+ * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Universes]]
+ * for more details.
*/
lazy val universe: api.JavaUniverse = new runtime.JavaUniverse
/** The runtime reflection mirror that corresponds to the current lexical context.
- * Is typically equivalent to `universe.runtimeMirror(getClass.getClassLoader)` invoked at the call site.
- * See [[scala.reflect.api.package the overview page]] for details on how to use it.
+ * It's typically equivalent to `universe.runtimeMirror(getClass.getClassLoader)` invoked at the call site.
*/
// implementation hardwired to the `currentMirror` method below
// using the mechanism implemented in `scala.tools.reflect.FastTrack`