summaryrefslogtreecommitdiff
path: root/src/library/scala/reflect/base/MirrorOf.scala
blob: 4e54a2fae7d41a85522b2758bf14e40961eac901 (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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package scala.reflect
package base

/**
 * The base interface for all mirrors.
 *
 * @tparam U the type of the universe this mirror belongs to. 
 * 
 * This is defined outside the reflection universe cake pattern implementation
 * so that it can be referenced from outside. For example TypeCreator and TreeCreator
 * reference MirrorOf and also need to be defined outside the cake as they are
 * used by type tags, which can be migrated between different universes and consequently
 * cannot be bound to a fixed one.
 *
 * @see [[Mirrors]]
 */
abstract class MirrorOf[U <: base.Universe with Singleton] {
  /** The universe this mirror belongs to. */
  val universe: U

  /** The class symbol of the `_root_` package */
  def RootClass: U#ClassSymbol

  /** The module symbol of the `_root_` package */
  def RootPackage: U#ModuleSymbol

  /** The module class symbol of the default (unnamed) package */
  def EmptyPackageClass: U#ClassSymbol

  /** The module symbol of the default (unnamed) package */
  def EmptyPackage: U#ModuleSymbol

  /** The symbol corresponding to the globally accessible class with the
   *  given fully qualified name `fullName`.
   *
   *  If the name points to a type alias, it's recursively dealiased and its target is returned.
   *  If you need a symbol that corresponds to the type alias itself, load it directly from the package class:
   *
   *    scala> cm.staticClass("scala.List")
   *    res0: reflect.runtime.universe.ClassSymbol = class List
   *
   *    scala> res0.fullName
   *    res1: String = scala.collection.immutable.List
   *
   *    scala> cm.staticPackage("scala")
   *    res2: reflect.runtime.universe.ModuleSymbol = package scala
   *
   *    scala> res2.moduleClass.typeSignature member newTypeName("List")
   *    res3: reflect.runtime.universe.Symbol = type List
   *
   *    scala> res3.fullName
   *    res4: String = scala.List
   *
   *  To be consistent with Scala name resolution rules, in case of ambiguity between
   *  a package and an object, the object is never been considered.
   *
   *  For example for the following code:
   *
   *    package foo {
   *      class B
   *    }
   *
   *    object foo {
   *      class A
   *      class B
   *    }
   *
   *  staticClass("foo.B") will resolve to the symbol corresponding to the class B declared in the package foo, and
   *  staticClass("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this
   *  fully qualified class name is written inside any package in a Scala program).
   *
   *  In the example above, to load a symbol that corresponds to the class B declared in the object foo,
   *  use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass.
   */
  def staticClass(fullName: String): U#ClassSymbol

  /** The symbol corresponding to the globally accessible object with the
   *  given fully qualified name `fullName`.
   *
   *  To be consistent with Scala name resolution rules, in case of ambiguity between
   *  a package and an object, the object is never been considered.
   *
   *  For example for the following code:
   *
   *    package foo {
   *      object B
   *    }
   *
   *    object foo {
   *      object A
   *      object B
   *    }
   *
   *  staticModule("foo.B") will resolve to the symbol corresponding to the object B declared in the package foo, and
   *  staticModule("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this
   *  fully qualified class name is written inside any package in a Scala program).
   *
   *  In the example above, to load a symbol that corresponds to the object B declared in the object foo,
   *  use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass.
   */
  def staticModule(fullName: String): U#ModuleSymbol

  /** The symbol corresponding to a package with the
   *  given fully qualified name `fullName`.
   */
  def staticPackage(fullName: String): U#ModuleSymbol
}