summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/api/package.scala
blob: 0b2a43936eb968542b9558c8b18be747388b81fc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package scala.reflect

import scala.reflect.api.{Universe => ApiUniverse}

/**
 * The main package of Scala's reflection library.
 *
 * The reflection library is structured according to the 'cake pattern'. The main layer
 * resides in package [[scala.reflect.api]] and defines an interface to the following main types:
 *
 *   - [[scala.reflect.api.Types#Type Types]] represent types
 *   - [[scala.reflect.api.Symbols#Symbol Symbols]] represent definitions
 *   - [[scala.reflect.api.Trees#Tree Trees]] represent abstract syntax trees
 *   - [[scala.reflect.api.Names#Name Names]] represent term and type names
 *   - [[scala.reflect.api.Annotations#Annotation Annotations]] represent annotations
 *   - [[scala.reflect.api.Positions#Position Positions]] represent source positions of tree nodes
 *   - [[scala.reflect.api.FlagSets#FlagSet FlagSet]] represent sets of flags that apply to symbols and
 *     definition trees
 *   - [[scala.reflect.api.Constants#Constant Constants]] represent compile-time constants.
 *
 * Each of these types are defined in their own enclosing traits, which are ultimately all inherited by class
 * [[scala.reflect.api.Universe Universe]]. The main universe defines a minimal interface to the above types.
 * Universes that provide additional functionality such as deeper introspection or runtime code generation,
 * are defined in packages [[scala.reflect.api]] and `scala.tools.reflect`.
 *
 * The cake pattern employed here requires to write certain Scala idioms with more indirections that usual.
 * What follows is a description of these indirections, which will help to navigate the Scaladocs easily.
 *
 * For instance, consider the base type of all abstract syntax trees: [[scala.reflect.api.Trees#Tree]].
 * This type is not a class but is abstract and has an upper bound of [[scala.reflect.api.Trees#TreeApi]],
 * which is a class defining the minimal base interface for all trees.
 *
 * For a more interesting tree type, consider [[scala.reflect.api.Trees#If]] representing if-expressions.
 * It is defined next to a value `If` of type [[scala.reflect.api.Trees#IfExtractor]].
 * This value serves as the companion object defining a factory method `apply` and a corresponding `unapply`
 * for pattern matching.
 *
 * {{{
 * import scala.reflect.runtime.universe._
 * val cond = reify{ condition }.tree // <- just some tree representing a condition
 * val body = Literal(Constant(1))
 * val other = Literal(Constant(2))
 * val iftree = If(cond,body,other)
 * }}}
 *
 * is equivalent to
 *
 * {{{
 * import scala.reflect.runtime.universe._
 * val iftree = reify{ if( condition ) 1 else 2 }.tree
 * }}}
 *
 * and can be pattern matched as
 *
 * {{{
 * iftree match { case If(cond,body,other) => ... }
 * }}}
 *
 * Moreover, there is an implicit value [[scala.reflect.api.Trees#IfTag]] of type
 * `ClassTag[If]` that is used by the Scala compiler so that we can indeed pattern match on `If`:
 * {{{
 *   iftree match { case _:If => ... }
 * }}}
 * Without the given implicit value, this pattern match would raise an "unchecked" warning at compile time
 * since `If` is an abstract type that gets erased at runtime. See [[scala.reflect.ClassTag]] for details.
 *
 * To summarize: each tree type `X` (and similarly for other types such as `Type` or `Symbol`) is represented
 * by an abstract type `X`, optionally together with a class `XApi` that defines `X`'s' interface.
 * `X`'s companion object, if it exists, is represented by a value `X` that is of type `XExtractor`.
 * Moreover, for each type `X`, there is a value `XTag` of type `ClassTag[X]` that allows to pattern match on `X`.
 */
package object api {

  // anchors for materialization macros emitted during tag materialization in Implicits.scala
  // implementation is hardwired into `scala.reflect.reify.Taggers`
  // using the mechanism implemented in `scala.tools.reflect.FastTrack`
  // todo. once we have implicit macros for tag generation, we can remove these anchors
  private[scala] def materializeWeakTypeTag[T](u: ApiUniverse): u.WeakTypeTag[T] = ??? // macro
  private[scala] def materializeTypeTag[T](u: ApiUniverse): u.TypeTag[T] = ??? // macro
}