summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Vogt <christopher.vogt@epfl.ch>2012-10-08 17:44:27 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-10-11 19:54:32 +0200
commit92dc8f81130b26475b0540a2226c340caac4c9ac (patch)
tree79b97c13fe48276dbe67dc388aee7717abb7fddf
parent6eb48f9602c3a21c85a38651c2e0b887e06b8d18 (diff)
downloadscala-92dc8f81130b26475b0540a2226c340caac4c9ac.tar.gz
scala-92dc8f81130b26475b0540a2226c340caac4c9ac.tar.bz2
scala-92dc8f81130b26475b0540a2226c340caac4c9ac.zip
reflection docs improvements and moves to doc page
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Typers.scala3
-rw-r--r--src/reflect/scala/reflect/api/JavaMirrors.scala8
-rw-r--r--src/reflect/scala/reflect/api/Names.scala35
-rw-r--r--src/reflect/scala/reflect/api/Positions.scala5
-rw-r--r--src/reflect/scala/reflect/api/package.scala206
5 files changed, 23 insertions, 234 deletions
diff --git a/src/compiler/scala/reflect/macros/runtime/Typers.scala b/src/compiler/scala/reflect/macros/runtime/Typers.scala
index be70181126..f9add91b9a 100644
--- a/src/compiler/scala/reflect/macros/runtime/Typers.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Typers.scala
@@ -8,6 +8,9 @@ trait Typers {
def openImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits
+ /**
+ * @see [[scala.tools.reflect.Toolbox.typeCheck]]
+ */
def typeCheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
macroLogVerbose("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled))
val context = callsiteTyper.context
diff --git a/src/reflect/scala/reflect/api/JavaMirrors.scala b/src/reflect/scala/reflect/api/JavaMirrors.scala
index e1219b2dde..e51047a7fe 100644
--- a/src/reflect/scala/reflect/api/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/api/JavaMirrors.scala
@@ -3,11 +3,9 @@ package api
/** 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).
- *
- * See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
+ * 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).
*/
trait JavaMirrors { self: JavaUniverse =>
diff --git a/src/reflect/scala/reflect/api/Names.scala b/src/reflect/scala/reflect/api/Names.scala
index c1de49a475..dccdd6868b 100644
--- a/src/reflect/scala/reflect/api/Names.scala
+++ b/src/reflect/scala/reflect/api/Names.scala
@@ -1,33 +1,20 @@
package scala.reflect
package api
-/** A slice of [[scala.reflect.api.Universe the Scala reflection cake]] that defines names and operations on them.
- * See [[scala.reflect.api.Universe]] for a description of how the reflection API is encoded with the cake pattern.
- *
- * Scala has separate namespaces for term names and type names. For example it is possible to have
- * a class named `C` and an object named `C` declared in the same lexical scope.
- *
- * Therefore the Scala reflection API models names using strongly-typed objects rather than strings:
- * [[scala.reflect.api.Names#TermName]] and [[scala.reflect.api.Names#TypeName]].
- *
- * A Name wraps a string as the name for either a type ([[TypeName]]) of a term ([[TermName]]).
- * Two names are equal, if the wrapped string are equal and they are either both `TypeName` or both `TermName`.
- * The same string can co-exist as a `TypeName` and a `TermName`, but they would not be equal.
- * Names are interned. That is, for two names `name1` and `name2`, `name1 == name2` implies `name1 eq name2`.
- * Name instances also can perform mangling and unmangling of symbolic names.
- *
+/** This trait defines Names (a Scala reflection concept) and operations on them.
+ *
+ * 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.
+ *
+ * @see [[http://docs.scala-lang.org/overviews/reflection/overview.html]].
+
* === Examples ===
*
- * To search for the `map` method declared in the `List` class, one uses
- * `typeOf[List[_]].member(newTermName("map"))` to explicitly specify that a term is looked up.
- *
- * An alternative notation makes use of implicit conversions from `String` to `TermName` and `TypeName`:
- * `typeOf[List[_]].member("map": TermName)`. Note that there's no implicit conversion from `String` to `Name`,
- * because it would be unclear whether such a conversion should produce a term name or a type name.
+ * To search for the `map` method (which is a term) declared in the `List` class,
+ * use `typeOf[List[_]].member(newTermName("map"))`. To search for a type member, use
+ * newTypeName instead.
*
- * Finally some names that bear special meaning for the compiler are defined in [[scala.reflect.api.StandardNames]].
- * For example, `WILDCARD` represents `_` and `CONSTRUCTOR` represents the standard JVM name for constructors, `<init>`.
- * Prefer using such constants instead of spelling the names out explicitly.
*/
trait Names {
/** An implicit conversion from String to TermName.
diff --git a/src/reflect/scala/reflect/api/Positions.scala b/src/reflect/scala/reflect/api/Positions.scala
index a47dc00f3d..bbb1fe45c4 100644
--- a/src/reflect/scala/reflect/api/Positions.scala
+++ b/src/reflect/scala/reflect/api/Positions.scala
@@ -1,10 +1,9 @@
package scala.reflect
package api
-/** A slice of [[scala.reflect.api.Universe the Scala reflection cake]] that defines positions and operations on them.
- * See [[scala.reflect.api.Universe]] for a description of how the reflection API is encoded with the cake pattern.
+/** This trait defines the concept of positions and operations on them.
*
- * The main documentation entry about positions is located at [[scala.reflect.api.Position]].
+ * @see [[scala.reflect.api.Position]]
*/
trait Positions {
self: Universe =>
diff --git a/src/reflect/scala/reflect/api/package.scala b/src/reflect/scala/reflect/api/package.scala
index d3eef59228..a11a269523 100644
--- a/src/reflect/scala/reflect/api/package.scala
+++ b/src/reflect/scala/reflect/api/package.scala
@@ -2,211 +2,13 @@ package scala.reflect
import scala.reflect.api.{Universe => ApiUniverse}
-/** The Scala reflection API.
+/** The Scala reflection API (located at scala-reflect.jar).
*
- * === Universes ===
- *
- * Standard reflection interfaces and implementations are all contained in the package scala-reflect.jar.
- * This jar is needed for all operations involving either Java reflection or macro implementations.
- * The two share a large set of operations, which are all abstracted out in the reflective core API in [[scala.reflect.api.Universe]].
- * This universe provides a fairly complete set of reflection operations that allow to query key Scala type relations such as membership or subtyping.
- *
- * [[scala.reflect.api.Universe]] has two specialized sub-universes. [[scala.reflect.api.JavaUniverse]] adds operations that link symbols and types
- * to the underlying classes and runtime values of a JVM. [[scala.reflect.macros.Universe]] adds operations which allow macros to access selected
- * compiler data structures and operations.
- *
- * The main implementation object of scala-reflect.jar is named [[scala.reflect.runtime.package#universe scala.reflect.runtime.universe]].
- * It is a global singleton, which serves as an entry point to runtime reflection.
- * There is no analogous global singleton universe for macros. Instead, macros access the currently running compiler instance as their universe,
- * accessible via [[scala.reflect.macros.Context#universe]].
- *
- * === Mirrors ===
- *
- * Each universe has one or more mirrors. A mirror defines a hierarchy of symbols starting with the root package
- * `_root_` and provides methods to locate and define classes and singleton objects in that hierarchy.
- * Mirrors for runtime reflection also provide operations to reflect on runtime instances.
- *
- * All universes have one root mirror each, available in the `rootMirror` field.
- * 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 the root mirror contains the root packages of all other mirrors as members.
- *
- * In a Java universe each mirror is associated with a classloader. This reflects the fact that multiple classes
- * with the same name can exist in a JVM instance, where each class is loaded by a different classloader.
- * To model this behavior, each JVM classloader is associated with a mirror, and each mirror contains its own
- * hierarchy of packages and classes. However, the same class may also exist in several different classloaders
- * and mirrors because classloaders can delegate to each other. This is modelled by one level of indirection:
- * several packages in different mirrors can link to the same class.
- *
- * The main access point to mirrors in runtime reflection is [[scala.reflect.runtime.package#currentMirror]],
- * which gives a JVM reflection mirror that corresponds to the current lexical context.
- * `currentMirror` is typically equivalent to `universe.runtimeMirror(getClass.getClassLoader)` invoked at the call site.
- * Macro universe is not based on classloaders, therefore it has only one mirror that corresponds to the compiler classpath,
- * accessible via [[scala.reflect.macros.Context#mirror]].
- *
- * === Toolboxes ===
- *
- * Along with runtime Java universe [[scala.reflect.api.Universe]] and compile-time macro universe [[scala.reflect.macros.Universe]],
- * reflection API also includes a runtime compiler universe implemented in `scala.tools.reflect`. One interacts with such universes
- * via toolboxes, instances of `scala.tools.reflect.ToolBox` declared in scala-compiler.jar.
- *
- * After importing the `scala.tools.reflect.ToolBox` implicit conversion, runtime reflection mirrors gain the `mkToolBox` method
- * that lets one create runtime compiler instances, optionally providing custom `options` string and a custom `frontEnd` that determines
- * how to process warnings and errors emitted by the compilers. Toolboxes have such methods as `parse`, `typeCheck`, `inferImplicitValue`, `compile` and `eval`.
- *
- * === Known issues ===
+ * Using Scala reflection requires understanding of a couple of basic concepts like Symbols, Types, Mirror and Universes.
+ * @see [[http://docs.scala-lang.org/overviews/reflection/overview.html]].
*
* 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. Here are some useful links:
- * - [[https://issues.scala-lang.org/secure/IssueNavigator.jspa?mode=hide&requestId=10908 Known issues in reflection and macros]]
- * - [[http://stackoverflow.com/questions/tagged/scala+reflection Questions tagged "scala" and "reflection" at Stack Overflow]]
- *
- * === Using runtime reflection ===
- *
- * Suppose we want to invoke the `head` method on `List(1, 2)`. This can be done in four steps, which include:
- * 1) setting up the environment, 2) getting to a symbol that represents `head`, 3) creating
- * a method mirror for `head`, 4) invoking the method mirror.
- *
- * === Step 1: Setting up the environment ===
- *
- * To do anything with reflection one needs to decide on a universe. The universe of choice for
- * runtime reflection is [[scala.reflect.runtime.package#universe scala.reflect.runtime.universe]].
- * A commonplace idiom is to do a blanket import `import scala.reflect.runtime.universe._` to get
- * access to all types and methods declared inside the universe.
- *
- * {{{
- * scala> import scala.reflect.runtime.universe._
- * import scala.reflect.runtime.universe._
- * }}}
- *
- * The next step is creating a mirror. On JVM mirrors are in one-to-one correspondence with classloaders.
- * Another common idiom is to create a mirror from `getClass.getClassLoader`, the classloader of the
- * current class. In most cases that will do, but if the structure of classloaders in your application
- * is more complex than that, adjust accordingly.
- *
- * {{{
- * scala> val cm = runtimeMirror(getClass.getClassLoader)
- * cm: reflect.runtime.universe.Mirror = JavaMirror with <translating classloader> of type
- * class scala.tools.nsc.interpreter.IMain$TranslatingClassLoader with classpath [(memory)]
- * and parent being <url classloader> of type class scala.tools.nsc.util.ScalaClassLoader$
- * URLClassLoader with classpath [file:/c:/PROGRA~1/Java/JDK/jre/lib/resources.jar...
- * }}}
- *
- * === Step 2: Getting to a symbol that represents `head` ===
- *
- * We start with obtaining a type of `List` to get to the `head` symbol that represents the given method.
- * There are three ways of doing that.
- *
- * The best way is to write `typeOf[List[Int]]`, which is applicable when the type
- * of the value being inspected is known in advance, and which gives the exact information about the type.
- * When the type is dynamic, we have to first obtain a Java class and then convert it to a Scala type,
- * e.g. `cm.runtimeClass(list.getClass).toType`. Unfortunately then the information about the type
- * suffers from erasure.
- *
- * {{{
- * scala> typeOf[List[Int]]
- * res0: reflect.runtime.universe.Type = scala.List[Int]
- *
- * scala> cm.classSymbol(List(1, 2).getClass).toType
- * res1: reflect.runtime.universe.Type = scala.collection.immutable.::[B]
- * }}}
- *
- * A compromise solution, which allows to preserve the exact type information, involves `TypeTag`
- * context bounds. If the value being inspected is an argument of a function, then we can make
- * the corresponding parameter generic and annotated the introduced type parameter with a type tag.
- * After we do that, the compiler will preserve exact types of arguments passed to a function,
- * available via `typeOf`.
- *
- * {{{
- * scala> def invokeHead(x: Any): Any = {
- * | // type of x is unknown, the best we can do is to approximate
- * | println(cm.classSymbol(x.getClass).toType)
- * | }
- * invokeHead: (x: Any)Any
- *
- * scala> invokeHead(List(1, 2))
- * scala.collection.immutable.::[B]
- *
- * scala> invokeHead(List("x"))
- * scala.collection.immutable.::[B]
- *
- * scala> def invokeHead[T: TypeTag](x: T): Any = {
- * | // type of x is preserved by the compiler
- * | println(typeOf[T])
- * | }
- * invokeHead: [T](x: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])Any
- *
- * scala> invokeHead(List(1, 2))
- * List[Int]
- *
- * scala> invokeHead(List("x"))
- * List[java.lang.String]
- * }}}
- *
- * Having a type at hand it is straightforward to traverse its members and obtain a symbol
- * that represents `head`.
- *
- * {{{
- * scala> val head = typeOf[List[Int]].member("head": TermName).asMethod
- * head: reflect.runtime.universe.MethodSymbol = method head
- * }}}
- *
- * Note the `asMethod` cast following the invocation of `member`. In Scala reflection symbol-returning methods
- * don't raise exceptions, but rather produce `NoSymbol`, a special singleton, which is a null object for symbols.
- * Therefore to use such APIs one has to first check whether a callee returned a valid symbol and, if yes, then perform
- * a cast using one of the `asTerm`, `asMethod`, `asModule`, `asType` or `asClass` methods.
- *
- * Also be careful with overloaded methods, which are represented as instances of `TermSymbol`, not `MethodSymbol`,
- * with multiple `alternatives` of type `MethodSymbol` that have to be resolved manually. This and other gotchas with
- * symbol loading are discussed on [[scala.reflect.api.Symbols the documentation page about symbols]].
- *
- * === Step 3: Creating a method mirror for `head` ===
- *
- * In Scala reflection, all reflective invocations go through mirrors created with `reflectXXX` methods.
- * For example, to get a singleton instance of an `object`, one needs to reflect a `ModuleSymbol` to obtain
- * a `ModuleMirror`, which provides the `instance` method.
- *
- * In our case we need to reflect an instance being processed, producing an `InstanceMirror`, then reflect
- * a method symbol loaded during the previous step, producing a `MethodMirror`. Finally, method mirrors
- * provide the `apply` method that performs reflective invocations.
- *
- * {{{
- * scala> val im = cm.reflect(List(1, 2))
- * im: reflect.runtime.universe.InstanceMirror = instance mirror for List(1, 2)
- *
- * scala> val mm = im.reflectMethod(head)
- * mm: reflect.runtime.universe.MethodMirror = method mirror for
- * scala.collection.IterableLike.head: A (bound to List(1, 2))
- * }}}
- *
- * === Step 4: Invoking the method mirror ===
- *
- * The final step is straightforward. Reflective invocation of a method is as simple as calling
- * the `apply` method of a `MethodMirror`:
- *
- * {{{
- * scala> mm()
- * res1 @ 758f3dae: Any = 1
- * }}}
- *
- * === Conclusion ===
- *
- * As specified in the documentation of traits declared in [[scala.reflect.api.Mirrors]],
- * in a similar fashion (by using `reflectXXX` methods), it is possible to:
- * - Get and set field values
- * - Instantiate classes
- * - Obtain singleton instances of objects
- *
- * However there's much more to Scala reflection, with examples on other documentation pages answering the following questions:
- * - [[scala.reflect.api.Symbols How to get a Symbol that corresponds to a given definition?]]
- * - [[scala.reflect.api.Types How to get a Type of some Scala code?]]
- * - [[scala.reflect.api.Trees How to get a Tree that corresponds to some Scala code?]]
- * - [[scala.reflect.api.Trees How to parse a string into a Tree?]]
- * - [[scala.reflect.api.Trees How to compile or evaluate a Tree?]]
- * - [[scala.reflect.api.Annotations How to get Java and/or Scala annotations attached to a given definition?]]
- * - [[scala.reflect.api.Printers How to inspect internal structure of reflection artifacts?]]
- * - [[scala.reflect.api.Importers How to move reflection artifacts from one universe to another?]]
- * - [[scala.reflect.macros.package How to use compile-time reflection in macros?]]
+ * in binary- and source-incompatible manner in 2.10.1. This also means that the implementation has known issues
*/
package object api {