reflectable.mirrors library

Basic reflection in Dart, with support for introspection and dynamic invocation.

Introspection is that subset of reflection by which a running program can examine its own structure. For example, a function that prints out the names of all the members of an arbitrary object.

Dynamic invocation refers the ability to evaluate code that has not been literally specified at compile time, such as calling a method whose name is provided as an argument (because it is looked up in a database, or provided interactively by the user).

How to interpret this library's documentation

The documentation frequently abuses notation with Dart pseudo-code such as o.x(a), where o and a are defined to be objects; what is actually meant in these cases is o'.x(a') where o' and a' are Dart variables bound to o and a respectively. Furthermore, o' and a' are assumed to be fresh variables (meaning that they are distinct from any other variables in the program).

The relation to dart:mirrors.

This library defines essentially the same types as the library dart:mirrors, in order to enable code using dart:mirrors to switch to using Reflectable based mirrors with a small porting effort. The changes are discussed below and mentioned in the documentation on the relevant declarations.

Required capabilities.

Differences in the set of declared entities.

Compared to the library dart:mirrors, a number of classes have been omitted, and some methods have been omitted from some classes, based on the need for those classes and the ability of the context to support those operations. For instance, Reflectable does not support the MirrorSystem class nor the currentMirrorSystem method, because the obligations ascribed to these entities are handled in a very different manner in Reflectable (a so-called reflector plays the role as a mirror system, multiple mirror systems can coexist, and none of them plays a special role that could justify calling it the "current" mirror system). A few additional methods have been added in cases where this was considered sufficiently useful and implementable.

Concretely, the elements which are present in dart:mirrors and absent from Reflectable are the following:

  • Class MirrorSystem: unnecessary.
  • Class IsolateMirror: not currently supported by Reflectable.
  • Top-level method currentMirrorSystem: unnecessary.
  • Top-level function reflectClass: unnecessary (use reflectType and originalDeclaration).
  • Top-level function reflectType: has become a method on Reflectable.
  • Top-level function reflect: has become a method on Reflectable.

Differences in mirror method signatures.

In contrast to dart.mirrors, reflective mirror operations return base values rather than mirrors. E.g., invoke in ObjectMirror has return type Object rather than InstanceMirror. If myObjectMirror is an ObjectMirror then evaluation of, e.g., myObjectMirror.invoke(..) will yield the same result as that of myObjectMirror.invoke(..).reflectee in dart:mirrors.

The rationale for this change is that it may be cheaper to return base values in typical scenarios (no mirror object is created, but it was often never used anyway) and there is no loss of information (we can get a mirror on the returned value if needed). Conceptually, it could be said that we move from the "pure" design where the reflective level is always preserved to a "practical" model where we return to the base level in selected cases.

Concretely, these cases are invoke, getField, and setField in ObjectMirror, newInstance in ClassMirror, and defaultValue in ParameterMirror, where the return type has been changed from InstanceMirror to Object. Similarly, the return type for metadata in DeclarationMirror and in LibraryDependencyMirror was changed from List<InstanceMirror> to List<Object>.


A ClassMirror reflects a Dart language class.
A ClosureMirror reflects a closure. [...]
A mirror on a show/hide combinator declared on a library dependency.
Class used for encoding comments as metadata annotations.
A DeclarationMirror reflects some entity declared in a Dart program.
A FunctionTypeMirror represents the type of a function in the Dart language.
An InstanceMirror reflects an instance of a Dart language object.
A mirror on an import or export declaration.
A LibraryMirror reflects a Dart language library, providing access to the variables, functions, and classes of the library.
A MethodMirror reflects a Dart language function, method, constructor, getter, or setter.
The base class for all mirrors.
An ObjectMirror is a common superinterface of InstanceMirror, ClassMirror, and LibraryMirror that represents their shared functionality. [...]
A ParameterMirror reflects a Dart formal parameter declaration.
A SourceLocation describes the span of an entity in Dart source code.
A TypedefMirror represents a typedef in a Dart language program.
A TypeMirror reflects a Dart language class, typedef, function type or type variable.
Used to obtain values of type Type. [...]
A TypeVariableMirror represents a type parameter of a generic type.
A VariableMirror reflects a Dart language variable declaration.