Basic reflection in Dart, with support for introspection and dynamic evaluation.
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 evaluation 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).
As a rule, the names of Dart declarations are represented using instances of class Symbol
. Whenever the doc speaks of an object s of class Symbol
denoting a name, it means the string that was used to construct s.
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).
Sometimes the documentation refers to serializable objects. An object is serializable across isolates if and only if it is an instance of num, bool, String, a list of objects that are serializable across isolates, or a map with keys and values that are all serializable across isolates.
Returns a MirrorSystem
for the current isolate.
Creates a MirrorSystem
for the isolate which is listening on the SendPort
.
Returns an InstanceMirror
reflecting reflectee
. If reflectee
is function or an instance of a class that has a call
method, the returned instance mirror will be a ClosureMirror
.
Note that since one cannot obtain an object from another isolate, this function can only be used to obtain mirrors on objects of the current isolate.
Let C be the original class declaration of the class represented by key
. This function returns a ClassMirror
reflecting C.
If key
is not an instance of Type
then this function throws an ArgumentError
. If key
is the Type dynamic, throws an ArgumentError
because dynamic is not a class.
Note that since one cannot obtain a Type
object from another isolate, this function can only be used to obtain class mirrors on classes of the current isolate.
A ClassMirror
reflects a Dart language class.
An immutable map from names to mirrors for all constructor declarations for this type.
An immutable map from names to mirrors for all getter declarations for this type.
Returns true if this mirror reflects a non-generic class or an instantiated generic class in the current isolate. Otherwise, returns false.
Is this the original declaration of this type?
For most classes, they are their own original declaration. For generic classes, however, there is a distinction between the original class declaration, which has unbound type variables, and the instantiations of generic classes, which have bound type variables.
An immutable map from from names to mirrors for all members of this type.
The members of a type are its methods, fields, getters, and setters. Note that constructors and type variables are not considered to be members of a type.
This does not include inherited members.
An immutable map from names to mirrors for all method, declarations for this type. This does not include getters and setters.
A mirror on the original declaration of this type.
For most classes, they are their own original declaration. For generic classes, however, there is a distinction between the original class declaration, which has unbound type variables, and the instantiations of generic classes, which have bound type variables.
If hasReflectedType
returns true, returns the corresponding Type
. Otherwise, an UnsupportedError
is thrown.
An immutable map from names to mirrors for all setter declarations for this type.
A mirror on the superclass on the reflectee.
If this type is Object
or a typedef, the superClass will be null.
A list of mirrors on the superinterfaces of the reflectee.
An immutable list with mirrors for all type arguments for this type.
If the the reflectee is an invocation of a generic class, the type arguments are the bindings of its type parameters. If the reflectee is the original declaration of a generic, it has no type arguments and this method returns an empty list. If the reflectee is a not generic, then it has no type arguments and this method returns an empty list.
This list preserves the order of declaration of the type variables.
An immutable list with mirrors for all type variables for this type.
If this type is a generic declaration or an invocation of a generic declaration, the returned list contains mirrors on the type variables. Otherwise, the returned list is empty.
This list preserves the order of declaration of the type variables.
An immutable map from names to mirrors for all variable declarations for this type.
Returns true
if this mirror is equal to other
. Otherwise returns false
.
The equality holds if and only if (1) other
is a mirror of the same kind and (2) This mirror and other
reflect the same class.
Note that if the reflected class is an invocation of a generic class,(2) implies that the reflected class and other
have equal type arguments.
Invokes the named constructor and returns a mirror on the result.
Let c be the class reflected by this mirror let a1, ..., an be the elements of positionalArguments
let k1, ..., km be the identifiers denoted by the elements of namedArguments.keys
and let v1, ..., vm be the elements of namedArguments.values
. If constructorName
was created from the empty string Then this method will execute the instance creation expression new c(a1, ..., an, k1: v1, ..., km: vm) in a scope that has access to the private members of c. Otherwise, let f be the simple name of the constructor denoted by constructorName
Then this method will execute the instance creation expression new c.f(a1, ..., an, k1: v1, ..., km: vm) in a scope that has access to the private members of c. In either case: If the expression evaluates to a result r, this method returns the result of calling reflect
(r). If evaluating the expression causes a compilation error this method throws a MirroredCompilationError
. If evaluating the expression throws an exception e (that it does not catch) this method throws e.
Invokes the named function and returns a mirror on the result. The arguments must be instances of InstanceMirror
, or of a type that is serializable across isolates (currently num
, String
, or bool
).
Let c be the class reflected by this mirror, let a1, ..., an be the elements of positionalArguments
let k1, ..., km be the identifiers denoted by the elements of namedArguments.keys
and let v1, ..., vm be the elements of namedArguments.values
. For each ai, if ai is an instance of InstanceMirror
, let pi be the object reflected by ai; otherwise let pi = ai, i in 1 ...n. Likewise, for each vj, if vj is an instance of InstanceMirror
, let qj be the object reflected by vj; otherwise let qj = vj, j in 1 ...m. If any of the pi, qj is not an instance of InstanceMirror
and is not serializable across isolates, an exception is thrown. If constructorName
was created from the empty string Then this method will execute the instance creation expression new c(a1, ..., an, k1: v1, ..., km: vm) in a scope that has access to the private members of c. Otherwise, let f be the simple name of the constructor denoted by constructorName
Then this method will execute the instance creation expression new c.f(a1, ..., an, k1: v1, ..., km: vm) in a scope that has access to the private members of c. In either case: The method returns a future k. If the invocation returns a result r, k will be completed with the result of calling reflect
(r). If the invocation throws an exception e (that it does not catch) then k is completed with a MirrorError
wrapping e.
A ClosureMirror
reflects a closure.
A ClosureMirror
provides access to its captured variables and provides the ability to execute its reflectee.
A mirror on the function associated with this closure.
Executes the closure and returns a mirror on the result. Let f be the closure reflected by this mirror, let a1, ..., an be the elements of positionalArguments
let k1, ..., km be the identifiers denoted by the elements of namedArguments.keys
and let v1, ..., vm be the elements of namedArguments.values
. Then this method will perform the method invocation f(a1, ..., an, k1: v1, ..., km: vm) If the invocation returns a result r, this method returns the result of calling reflect
(r). If the invocation causes a compilation error this method throws a MirrorError
. If the invocation throws an exception e (that it does not catch) this method throws e.
Executes the closure and returns a mirror on the result.
Let f be the closure reflected by this mirror, let a1, ..., an be the elements of positionalArguments
let k1, ..., km be the identifiers denoted by the elements of namedArguments.keys
and let v1, ..., vm be the elements of namedArguments.values
. For each ai, if ai is an instance of InstanceMirror
, let pi be the object reflected by ai; otherwise let pi = ai, i in 1 ...n. Likewise, for each vj, if vj is an instance of InstanceMirror
, let qj be the object reflected by vj; otherwise let qj = vj, j in 1 ...m. If any of the pi, qj is not an instance of InstanceMirror
and is not serializable across isolates, an exception is thrown. Then this method will perform the function invocation f(p1, ..., pn, k1: q1, ..., km: qm) The method returns a future k. If the invocation returns a result r, k will be completed with the result of calling reflect
(r). If the invocation throws an exception e (that it does not catch) then k is completed with a MirrorError
wrapping e.
The arguments must be instances of InstanceMirror
, or of a type that is serializable across isolates (currently num
, String
, or bool
).
Looks up the value of a name in the scope of the closure. The result is a mirror on that value.
Let s be the contents of the string used to construct the symbol name
.
If the expression s occurs within the source code of the reflectee, and that any such occurrence refers to a declaration outside the reflectee, then let v be the result of evaluating the expression s at such an occurrence. If s = this, and the reflectee was defined within the instance scope of an object o, then let v be o.
The returned value is the result of invoking the method reflect
on v.
Class used for encoding comments as metadata annotations.
Is true
if this comment is a documentation comment.
That is, that the comment is either enclosed in / ... */
or starts with ///
.
The comment text as written in the source text.
The comment text without the start, end, and padding text.
For example, if text
is / Comment text. */
then the trimmedText
is Comment text.
.
A DeclarationMirror
reflects some entity declared in a Dart program.
Returns true
if this declaration is considered private according to the Dart language specification. Always returns false
if this declaration is a library. Otherwise return false
.
Is this declaration top-level?
This is defined to be equivalent to: mirror.owner != null && mirror.owner is LibraryMirror
The source location of this Dart language entity.
A list of the metadata associated with this declaration.
Let D be the declaration this mirror reflects. If D is decorated with annotations A1, ..., An where n > 0, then for each annotation Ai associated with D, 1 <= i <= n, let ci be the constant object specified by Ai. Then this method returns a list whose members are instance mirrors on c1, ..., cn. If no annotations are associated with D, then an empty list is returned.
A mirror on the owner of this Dart language entity. This is the declaration immediately surrounding the reflectee.
For a library, the owner is null
. For a class declaration, typedef or top level function or variable, the owner is the enclosing library. For a mixin application S with M, the owner is the owner of M. For class Null, the owner is the dart:core library. For a constructor, the owner is the immediately enclosing class. For a method, instance variable or a static variable, the owner is the immediately enclosing class, unless the class is a mixin application S with M, in which case the owner is M. Note that M may be an invocation of a generic. For a parameter, local variable or local function the owner is the immediately enclosing function.
The fully-qualified name for this Dart language entity.
This name is qualified by the name of the owner. For instance, the qualified name of a method 'method' in class 'Class' in library 'library' is 'library.Class.method'.
Returns a Symbol
constructed from a string representing the fully qualified name of the reflectee. Let o be the owner
of this mirror, let r be the reflectee of this mirror, let p be the fully qualified name of the reflectee of o, and let s be the simple name of r computed by simpleName
. The fully qualified name of r is the concatenation of p, '.', and s.
Because an isolate can contain more than one library with the same name (at different URIs), a fully-qualified name does not uniquely identify any language entity.
The simple name for this Dart language entity.
The simple name is in most cases the the identifier name of the entity, such as 'method' for a method void method() {...}
or 'mylibrary' for a library 'mylibrary';
declaration.
A FunctionTypeMirror
represents the type of a function in the Dart language.
A mirror on the call
method for the reflectee.
Returns a list of the parameter types of the reflectee.
Returns the return type of the reflectee.
An InstanceMirror
reflects an instance of a Dart language object.
Does reflectee
contain the instance reflected by this mirror? This will always be true in the local case (reflecting instances in the same isolate), but only true in the remote case if this mirror reflects a simple value.
A value is simple if one of the following holds: - the value is null
- the value is of type num
- the value is of type bool
- the value is of type String
If the InstanceMirror
reflects an instance it is meaningful to have a local reference to, we provide access to the actual instance here.
If you access reflectee
when hasReflectee
is false, an exception is thrown.
A mirror on the type of the reflectee.
Returns a mirror on the actual class of the reflectee. The class of the reflectee may differ from the object returned by invoking runtimeType
on the reflectee.
Returns true if this mirror is equal to other
. The equality holds if and only if (1) other
is a mirror of the same kind and (2) either (a) hasReflectee
is true and so is identical(reflectee, other.reflectee)
or (b) the remote objects reflected by this mirror and by other
are identical.
Perform invocation
on reflectee
. Equivalent to
this.invoke(invocation.memberName,
invocation.positionalArguments, invocation.namedArguments);
An IsolateMirror
reflects an isolate.
Returns a unique name used to refer to an isolate in debugging messages.
Returns true
if and only if this mirror reflects the currently running isolate. Otherwise returns false
.
Returns a LibraryMirror
on the root library for this isolate.
Returns true
if this mirror is equal to other
. Otherwise returns false
. The equality holds if and only if (1) other
is a mirror of the same kind and (2) the isolate being reflected by this mirror is the same isolate being reflected by other
.
A LibraryMirror
reflects a Dart language library, providing access to the variables, functions, and classes of the library.
An immutable map from names to mirrors for all class declarations in this library.
An immutable map from names to mirrors for all function, getter, and setter declarations in this library.
An immutable map from names to mirrors for all getter declarations in this library.
An immutable map from from names to mirrors for all members in this library.
The members of a library are its top-level classes, functions, variables, getters, and setters.
An immutable map from names to mirrors for all setter declarations in this library.
The absolute uri of the library.
An immutable map from names to mirrors for all variable declarations in this library.
Returns true
if this mirror is equal to other
. Otherwise returns false
.
The equality holds if and only if (1) other
is a mirror of the same kind and (2) The library being reflected by this mirror and the library being reflected by other
are the same library in the same isolate.
A MethodMirror
reflects a Dart language function, method, constructor, getter, or setter.
The constructor name for named constructors and factory methods.
For unnamed constructors, this is the empty string. For non-constructors, this is the empty string.
For example, 'bar'
is the constructor name for constructor Foo.bar
of type Foo
.
Is the reflectee abstract?
Is the reflectee a const constructor?
Is the reflectee a constructor?
Is the reflectee a factory constructor?
Is the reflectee a generative constructor?
Is the reflectee a getter?
Is the reflectee an operator?
Is the reflectee a redirecting constructor?
Is the reflectee a regular function or method?
A function or method is regular if it is not a getter, setter, or constructor. Note that operators, by this definition, are regular methods.
Is the reflectee a setter?
Is the reflectee static?
For the purposes of the mirrors library, a top-level function is considered static.
A list of mirrors on the parameters for the reflectee.
A mirror on the return type for the reflectee.
The source code for the reflectee, if available. Otherwise null.
Returns true if this mirror is equal to other
.
The equality holds if and only if (1) other
is a mirror of the same kind and (2) simpleName == other.simpleName
and owner == other.owner
.
A Mirror
reflects some Dart language entity.
Every Mirror
originates from some MirrorSystem
.
The MirrorSystem
that contains this mirror.
A MirrorException
is used to indicate errors within the mirrors framework.
Returns a string representation of this object.
A MirrorSystem
is the main interface used to reflect on a set of associated libraries.
At runtime each running isolate has a distinct MirrorSystem
.
It is also possible to have a MirrorSystem
which represents a set of libraries which are not running -- perhaps at compile-time. In this case, all available reflective functionality would be supported, but runtime functionality (such as invoking a function or inspecting the contents of a variable) would fail dynamically.
A mirror on the dynamic
type.
A mirror on the isolate associated with this MirrorSystem
. This may be null if this mirror system is not running.
An immutable map from from library names to mirrors for all libraries known to this mirror system.
A mirror on the void
type.
Returns an iterable of all libraries in the mirror system whose library name is libraryName
.
Returns the name of symbol
.
The following text is non-normative:
Using this method may result in larger output. If possible, use MirrorsUsed
to specify which symbols must be retained in clear text.
When a compile-time error occurs during the mirrored execution of code, a MirroredCompilationError
is thrown.
This exception includes the compile-time error message that would have been displayed to the user, if the function had not been invoked via mirror.
Returns a string representation of this object.
When an error occurs during the mirrored execution of code, a MirroredError
is thrown.
In general, there are three main classes of failure that can happen during mirrored execution of code in some isolate:
- An exception is thrown but not caught. This is caught by the mirrors framework and a MirroredUncaughtExceptionError
is created and thrown.
- A compile-time error occurs, such as a syntax error. This is suppressed by the mirrors framework and a MirroredCompilationError
is created and thrown.
- A truly fatal error occurs, causing the isolate to be exited. If the reflector and reflectee share the same isolate, then they will both suffer. If the reflector and reflectee are in distinct isolates, then we hope to provide some information about the isolate death, but this has yet to be implemented.
TODO(turnidge): Specify the behavior for remote fatal errors.
When an uncaught exception occurs during the mirrored execution of code, a MirroredUncaughtExceptionError
is thrown.
This exception contains a mirror on the original exception object. It also contains an object which can be used to recover the stacktrace.
A mirror on the exception object.
The result of toString() for the exception object.
A stacktrace object for the uncaught exception.
Returns a string representation of this object.
EXPERIMENTAL API: Description of how "dart:mirrors" is used.
When used as metadata on an import of "dart:mirrors" in library L, this class describes how "dart:mirrors" is used by library L unless overridden. See override.
The following text is non-normative:
In some scenarios, for example, when minifying Dart code, or when generating JavaScript code from a Dart program, the size and performance of the output can suffer from use of reflection. In those cases, telling the compiler what is used, can have a significant impact.
Example usage:
@MirrorsUsed(symbols: 'foo', override: '*') import 'dart:mirrors'; class Foo { noSuchMethod(Invocation invocation) { print(Mirrors.getName(invocation.memberName)); } } main() { new Foo().foo(); // Prints "foo". new Foo().bar(); // Might print an arbitrary (mangled) name, "bar". }
A list of classes that when used as metadata indicates a reflective target.
See targets
.
A list of library names or "*".
When used as metadata on an import of "dart:mirrors", this metadata does not apply to the library in which the annotation is used, but instead applies to the other libraries (all libraries if "*" is used).
The list of strings passed to new Symbol
, and symbols that might be passed to MirrorSystem.getName
.
Combined with the names of targets
, metaTargets
and their members, this forms the complete list of strings passed to new Symbol
, and symbols that might be passed to MirrorSystem.getName
by the library to which this metadata applies.
The following text is non-normative:
Specifying this option turns off the following warnings emitted by dart2js:
Use symbols = "*" to turn off the warnings mentioned above.
For example, if using noSuchMethod
to interact with a database, extract all the possible column names and include them in this list. Similarly, if using noSuchMethod
to interact with another language (JavaScript, for example) extract all the identifiers from API used and include them in this list.
A list of reflective targets.
Combined with metaTargets
, this provides the complete list of reflective targets used by the library to which this metadata applies.
The following text is non-normative:
For now, there is no formal description of what a reflective target is. Informally, it is a list of things that are expected to have fully functional mirrors.
An ObjectMirror
is a common superinterface of InstanceMirror
, ClassMirror
, and LibraryMirror
that represents their shared functionality.
For the purposes of the mirrors library, these types are all object-like, in that they support method invocation and field access. Real Dart objects are represented by the InstanceMirror
type.
See InstanceMirror
, ClassMirror
, and LibraryMirror
.
Invokes a getter and returns a mirror on the result. The getter can be the implicit getter for a field or a user-defined getter method.
Let o be the object reflected by this mirror, let f be the simple name of the getter denoted by fieldName
, Then this method will perform the getter invocation o.f in a scope that has access to the private members of o (if o is a class or library) or the private members of the class of o (otherwise). If the invocation returns a result r, this method returns the result of calling reflect
(r). If the invocation causes a compilation error this method throws a MirroredCompilationError
. If the invocation throws an exception e (that it does not catch) this method throws e.
Invokes a getter and returns a mirror on the result. The getter can be the implicit getter for a field or a user-defined getter method.
Let o be the object reflected by this mirror, let f be the simple name of the getter denoted by fieldName
, Then this method will perform the getter invocation o.f in a scope that has access to the private members of o (if o is a class or library) or the private members of the class of o(otherwise). The method returns a future k. If the invocation returns a result r, k will be completed with the result of calling reflect
(r). If the invocation throws an exception e (that it does not catch) then k is completed with a MirrorError
wrapping e.
Invokes the named function and returns a mirror on the result.
Let o be the object reflected by this mirror, let f be the simple name of the member denoted by memberName
, let a1, ..., an be the elements of positionalArguments
let k1, ..., km be the identifiers denoted by the elements of namedArguments.keys
and let v1, ..., vm be the elements of namedArguments.values
. Then this method will perform the method invocation o.f(a1, ..., an, k1: v1, ..., km: vm) in a scope that has access to the private members of o (if o is a class or library) or the private members of the class of o (otherwise). If the invocation returns a result r, this method returns the result of calling reflect
(r). If the invocation causes a compilation error this method throws a MirroredCompilationError
. If the invocation throws an exception e (that it does not catch) this method throws e.
Invokes the named function and returns a mirror on the result. The arguments must be instances of InstanceMirror
, or of a type that is serializable across isolates (currently num
, String
, or bool
).
Let o be the object reflected by this mirror, let f be the simple name of the member denoted by memberName
, let a1, ..., an be the elements of positionalArguments
let k1, ..., km be the identifiers denoted by the elements of namedArguments.keys
and let v1, ..., vm be the elements of namedArguments.values
. For each ai, if ai is an instance of InstanceMirror
, let pi be the object reflected by ai; otherwise let pi = ai, i in 1 ...n. Likewise, for each vj, if vj is an instance of InstanceMirror
, let qj be the object reflected by vj; otherwise let qj = vj, j in 1 ...m. If any of the pi, qj is not an instance of InstanceMirror
and is not serializable across isolates, an exception is thrown. Then this method will perform the method invocation o.f(p1, ..., pn, k1: q1, ..., km: qm) in a scope that has access to the private members of o (if o is a class or library) or the private members of the class of o(otherwise). The method returns a future k. If the invocation returns a result r, k will be completed with the result of calling reflect
(r). If the invocation throws an exception e (that it does not catch) then k is completed with a MirrorError
wrapping e.
Invokes a setter and returns a mirror on the result. The setter may be either the implicit setter for a non-final field or a user-defined setter method.
Let o be the object reflected by this mirror, let f be the simple name of the getter denoted by fieldName
, and let a be the object bound to value
. Then this method will perform the setter invocation o.f = a in a scope that has access to the private members of o (if o is a class or library) or the private members of the class of o (otherwise). If the invocation returns a result r, this method returns the result of calling reflect
(value
). If the invocation causes a compilation error this method throws a MirroredCompilationError
. If the invocation throws an exception e (that it does not catch) this method throws e.
Invokes a setter and returns a mirror on the result. The setter may be either the implicit setter for a non-final field or a user-defined setter method. The second argument must be an instance of InstanceMirror
, or of a type that is serializable across isolates (currently num
, String
, or bool
).
Let o be the object reflected by this mirror, let f be the simple name of the getter denoted by fieldName
, and let a be the object bound to value
. If a is an instance of InstanceMirror
let p be the object reflected by a, otherwise let p =a. If p is not an instance of InstanceMirror
, p must be serializable across isolates or an exception is thrown. Then this method will perform the setter invocation o.f = a in a scope that has access to the private members of o (if o is a class or library) or the private members of the class of o(otherwise). The method returns a future k. If the invocation returns a result r, k will be completed with the result of calling reflect
(r). If the invocation throws an exception e (that it does not catch) then k is completed with a [MirrorError} wrapping e.
A ParameterMirror
reflects a Dart formal parameter declaration.
If this is a required parameter, returns null
. Otherwise returns a mirror on the default value for this parameter. If no default is declared for an optional parameter, the default is null
and a mirror on null
is returned.
Returns true
if the reflectee has explicitly declared a default value. Otherwise returns false
.
Returns true
if the reflectee is a named parameter. Otherwise returns false
.
Returns true
if the reflectee is an optional parameter. Otherwise returns false
.
A mirror on the type of this parameter.
A SourceLocation
describes the span of an entity in Dart source code.
A TypeMirror
reflects a Dart language class, typedef, or type variable.
A TypeVariableMirror
represents a type parameter of a generic type.
A mirror on the type that is the upper bound of this type variable.
Returns true
if this mirror is equal to other
. Otherwise returns false
.
The equality holds if and only if (1) other
is a mirror of the same kind and (2) simpleName == other.simpleName
and owner == other.owner
.
A TypedefMirror
represents a typedef in a Dart language program.
The defining type for this typedef.
For instance void f(int)
is the value for typedef void f(int)
.
A VariableMirror
reflects a Dart language variable declaration.
Returns true
if the reflectee is a final variable. Otherwise returns false
.
Returns true
if the reflectee is a static variable. Otherwise returns false
.
For the purposes of the mirror library, top-level variables are implicitly declared static.
Returns a mirror on the type of the reflectee.
Returns true if this mirror is equal to other
.
The equality holds if and only if (1) other
is a mirror of the same kind and (2) simpleName == other.simpleName
and owner == other.owner
.