5
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
7
* This trait provides support for Mirrors in the Scala Reflection API.
9
* `Mirror`s are a central part of Scala Reflection. All information provided by
10
* reflection is made accessible through `Mirror`s. Depending on the type of information
11
* to be obtained, or the reflective action to be taken, different flavors of mirrors
12
* must be used. "Classloader" mirrors can be used to obtain representations of types
13
* and members. From a classloader `Mirror`, it's possible to obtain more specialized
14
* "invoker" `Mirror`s (the most commonly-used mirrors), which implement reflective
15
* invocations, such as method/constructor calls and field accesses.
17
* The two flavors of mirrors:
20
* <li>'''“Classloader” mirrors'''. These mirrors translate names to symbols
21
* (via methods `staticClass`/`staticModule`/`staticPackage`).</li>
22
* <li>'''"Invoker” mirrors'''. These mirrors implement reflective invocations
23
* (via methods `MethodMirror.apply`, `FieldMirror.get`, etc). These "invoker"
24
* mirrors are the types of mirrors that are most commonly used.</li>
27
* === Compile-time Mirrors ===
28
* Compile-time `Mirror`s make use of only classloader `Mirror`s to load `Symbol`s
31
* The entry point to classloader `Mirror`s is via [[scala.reflect.macros.Context#mirror]].
32
* Typical methods which use classloader `Mirror`s include [[scala.reflect.api.Mirror#staticClass]],
33
* [[scala.reflect.api.Mirror#staticModule]], and [[scala.reflect.api.Mirror#staticPackage]]. For
36
* import scala.reflect.macros.Context
38
* case class Location(filename: String, line: Int, column: Int)
41
* def currentLocation: Location = macro impl
43
* def impl(c: Context): c.Expr[Location] = {
45
* val pos = c.macroApplication.pos
46
* val clsLocation = c.mirror.staticModule("Location") // get symbol of "Location" object
47
* c.Expr(Apply(Ident(clsLocation), List(Literal(Constant(pos.source.path)), Literal(Constant(pos.line)), Literal(Constant(pos.column)))))
52
* ''Of Note:'' There are several high-level alternatives that one can use to avoid having to manually
53
* lookup symbols. For example, `typeOf[Location.type].termSymbol` (or `typeOf[Location].typeSymbol`
54
* if we needed a `ClassSymbol`), which are type safe since we don’t have to use `String`s to lookup
57
* === Runtime Mirrors ===
59
* Runtime `Mirror`s make use of both classloader and invoker `Mirror`s.
61
* The entry point to `Mirror`s for use at runtime is via `ru.runtimeMirror(<classloader>)`, where
62
* `ru` is [[scala.reflect.runtime.universe]].
64
* The result of a [[scala.reflect.api.JavaMirrors#runtimeMirror]] call is a classloader mirror,
65
* of type [[scala.reflect.api.Mirrors#ReflectiveMirror]], which can load symbols by names as
66
* discussed above (in the “Compile-time” section).
68
* A classloader mirror can create invoker mirrors, which include: [[scala.reflect.api.Mirrors#InstanceMirror]],
69
* [[scala.reflect.api.Mirrors#MethodMirror]], [[scala.reflect.api.Mirrors#FieldMirror]],
70
* [[scala.reflect.api.Mirrors#ClassMirror]] and [[scala.reflect.api.Mirrors#ModuleMirror]].
72
* Examples of how these two types of `Mirror`s interact are available below.
74
* === Types of Mirrors, Their Use Cases & Examples ===
76
* '''[[scala.reflect.api.Mirrors#ReflectiveMirror]]'''. Used for loading `Symbol`s by name, and
77
* as an entry point into invoker mirrors. Entry point: `val m = ru.runtimeMirror(<classloader>)`.
80
* scala> val ru = scala.reflect.runtime.universe
81
* ru: scala.reflect.api.JavaUniverse = ...
83
* scala> val m = ru.runtimeMirror(getClass.getClassLoader)
84
* m: reflect.runtime.universe.Mirror = JavaMirror ...
87
* '''[[scala.reflect.api.Mirrors#InstanceMirror]]'''. Used for creating invoker `Mirror`s for methods
88
* and fields and for inner classes and inner objects (modules). Entry point: `val im = m.reflect(<value>)`.
91
* scala> class C { def x = 2 }
94
* scala> val im = m.reflect(new C)
95
* im: reflect.runtime.universe.InstanceMirror = instance mirror for C@3442299e
98
* '''[[scala.reflect.api.Mirrors#MethodMirror]]'''. Used for invoking instance methods (Scala only has
99
* instance methods-- methods of objects are instance methods of object instances, obtainable
100
* via `ModuleMirror.instance`). Entry point: `val mm = im.reflectMethod(<method symbol>)`.
103
* scala> val methodX = typeOf[C].declaration(newTermName("x")).asMethod
104
* methodX: reflect.runtime.universe.MethodSymbol = method x
106
* scala> val mm = im.reflectMethod(methodX)
107
* mm: reflect.runtime.universe.MethodMirror = method mirror for C.x: scala.Int (bound to C@3442299e)
113
* '''[[scala.reflect.api.Mirrors#FieldMirror]]'''. Used for getting/setting instance fields
114
* (Scala only has instance fields-- fields of objects are instance methods of object instances
115
* obtainable via ModuleMirror.instance). Entry point:
116
* `val fm = im.reflectMethod(<field or accessor symbol>)`.
119
* scala> class C { val x = 2; val y = 3 }
122
* scala> val m = ru.runtimeMirror(getClass.getClassLoader)
123
* m: reflect.runtime.universe.Mirror = JavaMirror ...
125
* scala> val im = m.reflect(new C)
126
* im: reflect.runtime.universe.InstanceMirror = instance mirror for C@5f0c8ac1
128
* scala> val fieldX = typeOf[C].declaration(newTermName("x")).asTerm.accessed.asTerm
129
* fieldX: reflect.runtime.universe.TermSymbol = value x
130
* scala> val fmX = im.reflectField(fieldX)
131
* fmX: reflect.runtime.universe.FieldMirror = field mirror for C.x (bound to C@5f0c8ac1)
136
* scala> fmX.set(3) // NOTE: can set an underlying value of an immutable field!
138
* scala> val fieldY = typeOf[C].declaration(newTermName("y")).asTerm.accessed.asTerm
139
* fieldY: reflect.runtime.universe.TermSymbol = variable y
141
* scala> val fmY = im.reflectField(fieldY)
142
* fmY: reflect.runtime.universe.FieldMirror = field mirror for C.y (bound to C@5f0c8ac1)
153
* '''[[scala.reflect.api.Mirrors#ClassMirror]]'''. Used for creating invoker mirrors for constructors.
154
* Entry points: for ''static classes'' `val cm1 = m.reflectClass(<class symbol>)`,
155
* for ''inner classes'' `val mm2 = im.reflectClass(<module symbol>)`.
158
* scala> case class C(x: Int)
161
* scala> val m = ru.runtimeMirror(getClass.getClassLoader)
162
* m: reflect.runtime.universe.Mirror = JavaMirror ...
164
* scala> val classC = typeOf[C].typeSymbol.asClass
166
* classC: reflect.runtime.universe.Symbol = class C
168
* scala> val cm = m.reflectClass(classC)
169
* cm: reflect.runtime.universe.ClassMirror = class mirror for C (bound to null)
171
* scala> val ctorC = typeOf[C].declaration(ru.nme.CONSTRUCTOR).asMethod
172
* ctorC: reflect.runtime.universe.MethodSymbol = constructor C
174
* scala> val ctorm = cm.reflectConstructor(ctorC)
175
* ctorm: reflect.runtime.universe.MethodMirror = constructor mirror for C.<init>(x: scala.Int): C (bound to null)
181
* '''[[scala.reflect.api.Mirrors#ModuleMirror]]'''. Used for getting singleton instances of objects.
182
* Entry points: for ''static objects (modules)'' `val mm1 = m.reflectModule(<module symbol>)`,
183
* for ''inner objects (modules)'' `val mm2 = im.reflectModule(<module symbol>)`.
186
* scala> object C { def x = 2 }
189
* scala> val m = ru.runtimeMirror(getClass.getClassLoader)
190
* m: reflect.runtime.universe.Mirror = JavaMirror ...
192
* scala> val objectC = typeOf[C.type].termSymbol.asModule
193
* objectC: reflect.runtime.universe.ModuleSymbol = object C
195
* scala> val mm = m.reflectModule(objectC)
196
* mm: reflect.runtime.universe.ModuleMirror = module mirror for C (bound to null)
198
* scala> val obj = mm.instance
199
* obj: Any = C$@1005ec04
202
* For more information about `Mirrors`s, see the
203
* [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]]
205
* @contentDiagram hideNodes "*Api"
206
* @group ReflectionAPI
208
trait Mirrors { self: Universe =>
210
/** The base type of all mirrors of this universe.
212
* This abstract type conforms the base interface for all mirrors defined in [[scala.reflect.api.Mirror]]
213
* and is gradually refined in specific universes (e.g. `Mirror` of a [[scala.reflect.api.JavaUniverse]] is capable of reflection).
216
type Mirror >: Null <: scala.reflect.api.Mirror[self.type]
218
/** The root mirror of this universe. This mirror contains standard Scala classes and types such as `Any`, `AnyRef`, `AnyVal`,
219
* `Nothing`, `Null`, and all classes loaded from scala-library, which are shared across all mirrors within the enclosing universe.
222
val rootMirror: Mirror
224
/** Abstracts the runtime representation of a class on the underlying platform.
227
type RuntimeClass >: Null
229
// todo. an improvement might be having mirrors reproduce the structure of the reflection domain
230
// e.g. a ClassMirror could also have a list of fields, methods, constructors and so on
231
// read up more on the proposed design in "Reflecting Scala" by Y. Coppel
233
/** A mirror that reflects a runtime value.
234
* See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
237
trait InstanceMirror {
239
/** The instance value reflected by this mirror */
242
/** The symbol corresponding to the runtime class of the reflected instance */
243
def symbol: ClassSymbol
245
/** Reflects against a field symbol and returns a mirror
246
* that can be used to get and, if appropriate, set the value of the field.
248
* FieldMirrors are the only way to get at private[this] vals and vars and
249
* might be useful to inspect the data of underlying Java fields.
250
* For all other uses, it's better to go through the fields accessor.
252
* In particular, there should be no need to ever access a field mirror
253
* when reflecting on just the public members of a class or trait.
254
* Note also that only accessor MethodMirrors, but not FieldMirrors will accurately reflect overriding behavior.
256
* To get a field symbol by the name of the field you would like to reflect,
257
* use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the field>)).asTerm.accessed`.
258
* For further information about member lookup refer to `Symbol.typeSignature`.
260
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
261
* It must be a member (declared or inherited) of the class of the instance underlying this mirror.
263
* The input symbol can represent either a field itself or one of the corresponding accessors
264
* (in all cases the resulting mirror will refer to the field symbol).
266
* If a field symbol doesn't correspond to a reflectable entity of the underlying platform,
267
* a `ScalaReflectionException` exception will be thrown. This might happen, for example, for primary constructor parameters.
268
* Typically they produce class fields, however, private parameters that aren't used outside the constructor
269
* remain plain parameters of a constructor method of the class.
271
def reflectField(field: TermSymbol): FieldMirror
273
/** Reflects against a method symbol and returns a mirror
274
* that can be used to invoke the method provided.
276
* To get a method symbol by the name of the method you would like to reflect,
277
* use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the method>)).asMethod`.
278
* For further information about member lookup refer to `Symbol.typeSignature`.
280
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
281
* It must be a member (declared or inherited) of the instance underlying this mirror.
283
def reflectMethod(method: MethodSymbol): MethodMirror
285
/** Reflects against an inner class symbol and returns a mirror
286
* that can be used to create instances of the class, inspect its companion object or perform further reflections.
288
* To get a class symbol by the name of the class you would like to reflect,
289
* use `<this mirror>.symbol.typeSignature.member(newTypeName(<name of the class>)).asClass`.
290
* For further information about member lookup refer to `Symbol.typeSignature`.
292
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
293
* It must be a member (declared or inherited) of the instance underlying this mirror.
295
def reflectClass(cls: ClassSymbol): ClassMirror
297
/** Reflects against an inner module symbol and returns a mirror
298
* that can be used to get the instance of the object or inspect its companion class.
300
* To get a module symbol by the name of the object you would like to reflect,
301
* use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the object>)).asModule`.
302
* For further information about member lookup refer to `Symbol.typeSignature`.
304
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
305
* It must be a member (declared or inherited) of the instance underlying this mirror.
307
def reflectModule(mod: ModuleSymbol): ModuleMirror
310
/** A mirror that reflects a field.
311
* See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
316
/** The object containing the field */
319
/** The field symbol representing the field.
321
* In Scala `val` and `var` declarations are usually compiled down to a pair of
322
* a backing field and corresponding accessor/accessors, which means that a single
323
* declaration might correspond to up to three different symbols. Nevertheless
324
* the `FieldMirror.symbol` field always points to a backing field symbol.
326
def symbol: TermSymbol
328
/** Retrieves the value stored in the field.
330
* Scala reflection uses reflection capabilities of the underlying platform,
331
* so `FieldMirror.get` might throw platform-specific exceptions associated
332
* with getting a field or invoking a getter method of the field.
334
* If `symbol` represents a field of a base class with respect to the class of the receiver,
335
* and this base field is overriden in the class of the receiver, then this method will retrieve
336
* the value of the base field. To achieve overriding behavior, use reflectMethod on an accessor.
340
/** Updates the value stored in the field.
342
* If a field is immutable, a `ScalaReflectionException` will be thrown.
344
* Scala reflection uses reflection capabilities of the underlying platform,
345
* so `FieldMirror.get` might throw platform-specific exceptions associated
346
* with setting a field or invoking a setter method of the field.
348
* If `symbol` represents a field of a base class with respect to the class of the receiver,
349
* and this base field is overriden in the class of the receiver, then this method will set
350
* the value of the base field. To achieve overriding behavior, use reflectMethod on an accessor.
352
def set(value: Any): Unit
355
/** A mirror that reflects a method.
356
* See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
361
/** The receiver object of the method */
364
/** The method symbol representing the method */
365
def symbol: MethodSymbol
367
/** The result of applying the method to the given arguments
369
* Scala reflection uses reflection capabilities of the underlying platform,
370
* so `FieldMirror.get` might throw platform-specific exceptions associated
371
* with invoking the corresponding method or constructor.
373
def apply(args: Any*): Any
376
/** A mirror that reflects the instance or static parts of a runtime class.
377
* See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
380
trait TemplateMirror {
382
/** True if the mirror represents the static part
383
* of a runtime class or the companion object of a Scala class.
386
* this.isStatic == this.isInstanceOf[ModuleMirror]
387
* !this.isStatic == this.isInstanceOf[ClassMirror]
389
def isStatic: Boolean
391
/** The Scala symbol corresponding to the reflected runtime class or object */
395
/** A mirror that reflects a Scala object definition or the static parts of a runtime class.
396
* See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
399
trait ModuleMirror extends TemplateMirror {
401
/** The Scala module symbol corresponding to the reflected object */
402
override def symbol: ModuleSymbol
404
/** If the reflected runtime class corresponds to a Scala object definition,
405
* returns the single instance representing that object.
406
* If this mirror reflects the static part of a runtime class, returns `null`.
411
/** A mirror that reflects the instance parts of a runtime class.
412
* See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
415
trait ClassMirror extends TemplateMirror {
417
/** The Scala class symbol corresponding to the reflected class */
418
override def symbol: ClassSymbol
420
/** Reflects against a constructor symbol and returns a mirror
421
* that can be used to invoke it and construct instances of this mirror's symbols.
423
* To get a constructor symbol you would like to reflect,
424
* use `<this mirror>.symbol.typeSignature.member(nme.CONSTRUCTOR).asMethod`.
425
* For further information about member lookup refer to `Symbol.typeSignature`.
427
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
428
* It must be a member (declared or inherited) of the class underlying this mirror.
430
def reflectConstructor(constructor: MethodSymbol): MethodMirror
433
/** A mirror that reflects instances and static classes.
434
* See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
437
trait ReflectiveMirror extends scala.reflect.api.Mirror[Mirrors.this.type] {
439
/** A reflective mirror for the given object.
441
* Such a mirror can be used to further reflect against the members of the object
442
* to get/set fields, invoke methods and inspect inner classes and objects.
444
// we need a ClassTag here to preserve boxity of primitives
445
// the class tag lets us tell apart `mirror.reflect(2)` and `mirror.reflect(new Integer(2))`
446
def reflect[T: ClassTag](obj: T): InstanceMirror
448
/** Reflects against a static class symbol and returns a mirror
449
* that can be used to create instances of the class, inspect its companion object or perform further reflections.
451
* To get a class symbol by the name of the class you would like to reflect,
452
* use `<this mirror>.classSymbol(<runtime class loaded by its name>)`.
454
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
455
* It must be static, i.e. either top-level or nested within one or several static objects.
457
def reflectClass(cls: ClassSymbol): ClassMirror
459
/** Reflects against a static module symbol and returns a mirror
460
* that can be used to get the instance of the object or inspect its companion class.
462
* To get a module symbol by the name of its companion class you would like to reflect,
463
* use `<this mirror>.classSymbol(<runtime class loaded by its name>).companion.get`.
465
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
466
* It must be static, i.e. either top-level or nested within one or several static objects.
468
def reflectModule(mod: ModuleSymbol): ModuleMirror
471
/** The API of a mirror for a reflective universe.
472
* See [[scala.reflect.api.package the overview page]] for details on how to use runtime reflection.
475
trait RuntimeMirror extends ReflectiveMirror { self =>
477
/** Maps a Scala type to the corresponding Java class object */
478
def runtimeClass(tpe: Type): RuntimeClass
480
/** Maps a Scala class symbol to the corresponding Java class object
481
* @throws ClassNotFoundException if there is no Java class
482
* corresponding to the given Scala class symbol.
483
* Note: If the Scala symbol is ArrayClass, a ClassNotFound exception is thrown
484
* because there is no unique Java class corresponding to a Scala generic array
486
def runtimeClass(cls: ClassSymbol): RuntimeClass
488
/** A class symbol for the specified runtime class.
489
* @return The class symbol for the runtime class in the current class loader.
490
* @throws java.lang.ClassNotFoundException if no class with that name exists
491
* @throws scala.reflect.internal.MissingRequirementError if no corresponding symbol exists
492
* to do: throws anything else?
494
def classSymbol(rtcls: RuntimeClass): ClassSymbol
496
/** A module symbol for the specified runtime class.
497
* @return The module symbol for the runtime class in the current class loader.
498
* @throws java.lang.ClassNotFoundException if no class with that name exists
499
* @throws scala.reflect.internal.MissingRequirementError if no corresponding symbol exists
500
* to do: throws anything else?
502
def moduleSymbol(rtcls: RuntimeClass): ModuleSymbol