mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:00:09 +00:00
1451 lines
48 KiB
Dart
1451 lines
48 KiB
Dart
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
// For the purposes of the mirrors library, we adopt a naming
|
|
// convention with respect to getters and setters. Specifically, for
|
|
// some variable or field...
|
|
//
|
|
// var myField;
|
|
//
|
|
// ...the getter is named 'myField' and the setter is named
|
|
// 'myField='. This allows us to assign unique names to getters and
|
|
// setters for the purposes of member lookup.
|
|
|
|
/**
|
|
* 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
|
|
*
|
|
* 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.
|
|
*
|
|
* ## Status: Unstable
|
|
*
|
|
* The dart:mirrors library is unstable and its API might change slightly as a
|
|
* result of user feedback. This library is platform dependent and therefore it
|
|
* has implementations for both dart2js and the Dart VM. Both are under
|
|
* development and may not support all operations yet.
|
|
*/
|
|
library dart.mirrors;
|
|
|
|
import 'dart:async' show Future;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
abstract class MirrorSystem {
|
|
/**
|
|
* All libraries known to the mirror system, indexed by their URI.
|
|
*
|
|
* Returns an unmodifiable map of the libraries with [LibraryMirror.uri] as
|
|
* keys.
|
|
*
|
|
* For a runtime mirror system, only libraries which are currently loaded
|
|
* are included, and repeated calls of this method may return different maps
|
|
* as libraries are loaded.
|
|
*/
|
|
Map<Uri, LibraryMirror> get libraries;
|
|
|
|
/**
|
|
* Returns the unique library named [libraryName] if it exists.
|
|
*
|
|
* If no unique library exists, an error is thrown.
|
|
*/
|
|
LibraryMirror findLibrary(Symbol libraryName) {
|
|
return libraries.values.singleWhere(
|
|
(library) => library.simpleName == libraryName);
|
|
}
|
|
|
|
/**
|
|
* A mirror on the isolate associated with this [MirrorSystem].
|
|
*
|
|
* This may be null if this mirror system is not running.
|
|
*/
|
|
IsolateMirror get isolate;
|
|
|
|
/**
|
|
* A mirror on the [:dynamic:] type.
|
|
*/
|
|
TypeMirror get dynamicType;
|
|
|
|
/**
|
|
* A mirror on the [:void:] type.
|
|
*/
|
|
TypeMirror get voidType;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
external static String getName(Symbol symbol);
|
|
|
|
/**
|
|
* Returns a symbol for [name].
|
|
*
|
|
* If [library] is not a [LibraryMirror] or if [name] is a private identifier
|
|
* and [library] is `null`, throws an [ArgumentError]. If [name] is a private
|
|
* identifier, the symbol returned is with respect to [library].
|
|
*
|
|
* The following text is non-normative:
|
|
*
|
|
* Using this method may result in larger output. If possible, use
|
|
* the const constructor of [Symbol] or symbol literals.
|
|
*/
|
|
external static Symbol getSymbol(String name, [LibraryMirror library]);
|
|
}
|
|
|
|
/**
|
|
* Returns a [MirrorSystem] for the current isolate.
|
|
*/
|
|
external MirrorSystem currentMirrorSystem();
|
|
|
|
/**
|
|
* Reflects an instance.
|
|
*
|
|
* Returns an [InstanceMirror] reflecting [reflectee]. If [reflectee] is a
|
|
* 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.
|
|
*/
|
|
external InstanceMirror reflect(Object reflectee);
|
|
|
|
/**
|
|
* Reflects a class declaration.
|
|
*
|
|
* 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 for dynamic or a function typedef,
|
|
* throws an [ArgumentError].
|
|
*
|
|
* 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.
|
|
*/
|
|
external ClassMirror reflectClass(Type key);
|
|
|
|
/**
|
|
* Reflects the type represented by [key].
|
|
*
|
|
* If [key] is not an instance of [Type], then this function throws an
|
|
* [ArgumentError].
|
|
*
|
|
* Note that since one cannot obtain a [Type] object from another isolate, this
|
|
* function can only be used to obtain type mirrors on types of the current
|
|
* isolate.
|
|
*/
|
|
external TypeMirror reflectType(Type key);
|
|
|
|
/**
|
|
* A [Mirror] reflects some Dart language entity.
|
|
*
|
|
* Every [Mirror] originates from some [MirrorSystem].
|
|
*/
|
|
abstract class Mirror {}
|
|
|
|
/**
|
|
* An [IsolateMirror] reflects an isolate.
|
|
*/
|
|
abstract class IsolateMirror implements Mirror {
|
|
/**
|
|
* A unique name used to refer to the isolate in debugging messages.
|
|
*/
|
|
String get debugName;
|
|
|
|
/**
|
|
* Whether this mirror reflects the currently running isolate.
|
|
*/
|
|
bool get isCurrent;
|
|
|
|
/**
|
|
* The root library for the reflected isolate.
|
|
*/
|
|
LibraryMirror get rootLibrary;
|
|
|
|
/**
|
|
* Whether [other] is an [IsolateMirror] on the same isolate as this mirror.
|
|
*
|
|
* 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].
|
|
*/
|
|
bool operator == (other);
|
|
}
|
|
|
|
/**
|
|
* A [DeclarationMirror] reflects some entity declared in a Dart program.
|
|
*/
|
|
abstract class DeclarationMirror implements Mirror {
|
|
/**
|
|
* The simple name for this Dart language entity.
|
|
*
|
|
* The simple name is in most cases the identifier name of the entity,
|
|
* such as 'myMethod' for a method, [:void myMethod() {...}:] or 'mylibrary'
|
|
* for a [:library 'mylibrary';:] declaration.
|
|
*/
|
|
Symbol get simpleName;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
Symbol get qualifiedName;
|
|
|
|
/**
|
|
* A mirror on the owner of this Dart language entity.
|
|
*
|
|
* The owner 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 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.
|
|
*/
|
|
DeclarationMirror get owner;
|
|
|
|
/**
|
|
* Whether this declaration is library private.
|
|
*
|
|
* Always returns `false` for a library declaration,
|
|
* otherwise returns `true` if the declaration's name starts with an
|
|
* underscore character (`_`), and `false` if it doesn't.
|
|
*/
|
|
bool get isPrivate;
|
|
|
|
/**
|
|
* Whether this declaration is top-level.
|
|
*
|
|
* A declaration is considered top-level if its [owner] is a [LibraryMirror].
|
|
*/
|
|
bool get isTopLevel;
|
|
|
|
/**
|
|
* The source location of this Dart language entity, or [:null:] if the
|
|
* entity is synthetic.
|
|
*
|
|
* If the reflectee is a variable, the returned location gives the position
|
|
* of the variable name at its point of declaration.
|
|
*
|
|
* If the reflectee is a library, class, typedef, function or type variable
|
|
* with associated metadata, the returned location gives the position of the
|
|
* first metadata declaration associated with the reflectee.
|
|
*
|
|
* Otherwise:
|
|
*
|
|
* If the reflectee is a library, the returned location gives the position of
|
|
* the keyword 'library' at the reflectee's point of declaration, if the
|
|
* reflectee is a named library, or the first character of the first line in
|
|
* the compilation unit defining the reflectee if the reflectee is anonymous.
|
|
*
|
|
* If the reflectee is an abstract class, the returned location gives the
|
|
* position of the keyword 'abstract' at the reflectee's point of declaration.
|
|
* Otherwise, if the reflectee is a class, the returned location gives the
|
|
* position of the keyword 'class' at the reflectee's point of declaration.
|
|
*
|
|
* If the reflectee is a typedef the returned location gives the position of
|
|
* the of the keyword 'typedef' at the reflectee's point of declaration.
|
|
*
|
|
* If the reflectee is a function with a declared return type, the returned
|
|
* location gives the position of the function's return type at the
|
|
* reflectee's point of declaration. Otherwise. the returned location gives
|
|
* the position of the function's name at the reflectee's point of
|
|
* declaration.
|
|
*
|
|
* This operation is optional and may throw an [UnsupportedError].
|
|
*/
|
|
SourceLocation get location;
|
|
|
|
/**
|
|
* 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.
|
|
*
|
|
* If evaluating any of *c1, ..., cn* would cause a
|
|
* compilation error
|
|
* the effect is the same as if a non-reflective compilation error
|
|
* had been encountered.
|
|
*/
|
|
List<InstanceMirror> get metadata;
|
|
}
|
|
|
|
/**
|
|
* 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].
|
|
*/
|
|
abstract class ObjectMirror implements Mirror {
|
|
|
|
/**
|
|
* 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 the effect is the same as if
|
|
* a non-reflective compilation error had been encountered.
|
|
*
|
|
* If the invocation throws an exception *e* (that it does not catch), this
|
|
* method throws *e*.
|
|
*/
|
|
/*
|
|
* TODO(turnidge): Handle ambiguous names.
|
|
* TODO(turnidge): Handle optional & named arguments.
|
|
*/
|
|
InstanceMirror invoke(Symbol memberName,
|
|
List positionalArguments,
|
|
[Map<Symbol,dynamic> namedArguments]);
|
|
|
|
/**
|
|
* 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 this mirror is an [InstanceMirror], and [fieldName] denotes an instance
|
|
* method on its reflectee, the result of the invocation is an instance
|
|
* mirror on a closure corresponding to that method.
|
|
*
|
|
* If this mirror is a [LibraryMirror], and [fieldName] denotes a top-level
|
|
* method in the corresponding library, the result of the invocation is an
|
|
* instance mirror on a closure corresponding to that method.
|
|
*
|
|
* If this mirror is a [ClassMirror], and [fieldName] denotes a static method
|
|
* in the corresponding class, the result of the invocation is an instance
|
|
* mirror on a closure corresponding to that method.
|
|
*
|
|
* If the invocation returns a result *r*, this method returns the result of
|
|
* calling [reflect]\(*r*\).
|
|
*
|
|
* If the invocation causes a compilation error, the effect is the same as if
|
|
* a non-reflective compilation error had been encountered.
|
|
*
|
|
* If the invocation throws an exception *e* (that it does not catch), this
|
|
* method throws *e*.
|
|
*/
|
|
// TODO(ahe): Remove stuff about scope and private members. [fieldName] is a
|
|
// capability giving access to private members.
|
|
InstanceMirror getField(Symbol fieldName);
|
|
|
|
/**
|
|
* 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, the effect is the same as if
|
|
* a non-reflective compilation error had been encountered.
|
|
*
|
|
* If the invocation throws an exception *e* (that it does not catch) this
|
|
* method throws *e*.
|
|
*/
|
|
/* TODO(turnidge): Handle ambiguous names.*/
|
|
InstanceMirror setField(Symbol fieldName, Object value);
|
|
|
|
/**
|
|
* Performs [invocation] on [reflectee].
|
|
*
|
|
* Equivalent to
|
|
*
|
|
* if (invocation.isGetter) {
|
|
* return this.getField(invocation.memberName).reflectee;
|
|
* } else if (invocation.isSetter) {
|
|
* return this.setField(invocation.memberName,
|
|
* invocation.positionArguments[0]).reflectee;
|
|
* } else {
|
|
* return this.invoke(invocation.memberName,
|
|
* invocation.positionalArguments,
|
|
* invocation.namedArguments).reflectee;
|
|
* }
|
|
*/
|
|
delegate(Invocation invocation);
|
|
}
|
|
|
|
/**
|
|
* An [InstanceMirror] reflects an instance of a Dart language object.
|
|
*/
|
|
abstract class InstanceMirror implements ObjectMirror {
|
|
/**
|
|
* 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.
|
|
*/
|
|
ClassMirror get type;
|
|
|
|
/**
|
|
* Whether [reflectee] will return 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]
|
|
*/
|
|
bool get hasReflectee;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
get reflectee;
|
|
|
|
/**
|
|
* Whether 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.
|
|
*/
|
|
bool operator == (other);
|
|
}
|
|
|
|
/**
|
|
* A [ClosureMirror] reflects a closure.
|
|
*
|
|
* A [ClosureMirror] provides the ability to execute its reflectee and
|
|
* introspect its function.
|
|
*/
|
|
abstract class ClosureMirror implements InstanceMirror {
|
|
/**
|
|
* A mirror on the function associated with this closure.
|
|
*
|
|
* The function associated with an implicit closure of a function is that
|
|
* function.
|
|
*
|
|
* The function associated with an instance of a class that has a [:call:]
|
|
* method is that [:call:] method.
|
|
*
|
|
* A Dart implementation might choose to create a class for each closure
|
|
* expression, in which case [:function:] would be the same as
|
|
* [:type.declarations[#call]:]. But the Dart language model does not require
|
|
* this. A more typical implementation involves a single closure class for
|
|
* each type signature, where the call method dispatches to a function held
|
|
* in the closure rather the call method
|
|
* directly implementing the closure body. So one cannot rely on closures from
|
|
* distinct closure expressions having distinct classes ([:type:]), but one
|
|
* can rely on them having distinct functions ([:function:]).
|
|
*/
|
|
MethodMirror get function;
|
|
|
|
/**
|
|
* 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, the effect is the same as if
|
|
* a non-reflective compilation error had been encountered.
|
|
*
|
|
* If the invocation throws an exception *e* (that it does not catch), this
|
|
* method throws *e*.
|
|
*/
|
|
InstanceMirror apply(List positionalArguments,
|
|
[Map<Symbol, dynamic> namedArguments]);
|
|
}
|
|
|
|
/**
|
|
* A [LibraryMirror] reflects a Dart language library, providing
|
|
* access to the variables, functions, and classes of the
|
|
* library.
|
|
*/
|
|
abstract class LibraryMirror implements DeclarationMirror, ObjectMirror {
|
|
/**
|
|
* The absolute uri of the library.
|
|
*/
|
|
Uri get uri;
|
|
|
|
/**
|
|
* Returns an immutable map of the declarations actually given in the library.
|
|
*
|
|
* This map includes all regular methods, getters, setters, fields, classes
|
|
* and typedefs actually declared in the library. The map is keyed by the
|
|
* simple names of the declarations.
|
|
*/
|
|
Map<Symbol, DeclarationMirror> get declarations;
|
|
|
|
/**
|
|
* Whether this mirror is equal to [other].
|
|
*
|
|
* 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.
|
|
*/
|
|
bool operator ==(other);
|
|
|
|
/**
|
|
* Returns a list of the imports and exports in this library;
|
|
*/
|
|
List<LibraryDependencyMirror> get libraryDependencies;
|
|
}
|
|
|
|
/// A mirror on an import or export declaration.
|
|
abstract class LibraryDependencyMirror implements Mirror {
|
|
/// Is `true` if this dependency is an import.
|
|
bool get isImport;
|
|
|
|
/// Is `true` if this dependency is an export.
|
|
bool get isExport;
|
|
|
|
/// Returns true iff this dependency is a deferred import. Otherwise returns
|
|
/// false.
|
|
bool get isDeferred;
|
|
|
|
/// Returns the library mirror of the library that imports or exports the
|
|
/// [targetLibrary].
|
|
LibraryMirror get sourceLibrary;
|
|
|
|
/// Returns the library mirror of the library that is imported or exported,
|
|
/// or null if the library is not loaded.
|
|
LibraryMirror get targetLibrary;
|
|
|
|
/// Returns the prefix if this is a prefixed import and `null` otherwise.
|
|
Symbol get prefix;
|
|
|
|
/// Returns the list of show/hide combinators on the import/export
|
|
/// declaration.
|
|
List<CombinatorMirror> get combinators;
|
|
|
|
/// Returns the source location for this import/export declaration.
|
|
SourceLocation get location;
|
|
|
|
List<InstanceMirror> get metadata;
|
|
|
|
/// Returns a future that completes with a library mirror on the library being
|
|
/// imported or exported when it is loaded, and initiates a load of that
|
|
/// library if it is not loaded.
|
|
Future<LibraryMirror> loadLibrary();
|
|
}
|
|
|
|
/// A mirror on a show/hide combinator declared on a library dependency.
|
|
abstract class CombinatorMirror implements Mirror {
|
|
/// The list of identifiers on the combinator.
|
|
List<Symbol> get identifiers;
|
|
|
|
/// Is `true` if this is a 'show' combinator.
|
|
bool get isShow;
|
|
|
|
/// Is `true` if this is a 'hide' combinator.
|
|
bool get isHide;
|
|
}
|
|
|
|
/**
|
|
* A [TypeMirror] reflects a Dart language class, typedef,
|
|
* function type or type variable.
|
|
*/
|
|
abstract class TypeMirror implements DeclarationMirror {
|
|
/**
|
|
* Returns true if this mirror reflects dynamic, a non-generic class or
|
|
* typedef, or an instantiated generic class or typedef in the current
|
|
* isolate. Otherwise, returns false.
|
|
*/
|
|
bool get hasReflectedType;
|
|
|
|
/**
|
|
* If [:hasReflectedType:] returns true, returns the corresponding [Type].
|
|
* Otherwise, an [UnsupportedError] is thrown.
|
|
*/
|
|
Type get reflectedType;
|
|
|
|
/**
|
|
* 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
|
|
* declared in the original declaration.
|
|
* Otherwise, the returned list is empty.
|
|
*
|
|
* This list preserves the order of declaration of the type variables.
|
|
*/
|
|
List<TypeVariableMirror> get typeVariables;
|
|
|
|
/**
|
|
* An immutable list with mirrors for all type arguments for
|
|
* this type.
|
|
*
|
|
* If 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 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.
|
|
*/
|
|
List<TypeMirror> get typeArguments;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
bool get isOriginalDeclaration;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
TypeMirror get originalDeclaration;
|
|
|
|
|
|
/**
|
|
* Checks the subtype relationship, denoted by `<:` in the language
|
|
* specification.
|
|
*
|
|
* This is the type relationship used in `is` test checks.
|
|
*/
|
|
bool isSubtypeOf(TypeMirror other);
|
|
|
|
/**
|
|
* Checks the assignability relationship, denoted by `<=>` in the language
|
|
* specification.
|
|
*
|
|
* This is the type relationship tested on assignment in checked mode.
|
|
*/
|
|
bool isAssignableTo(TypeMirror other);
|
|
}
|
|
|
|
/**
|
|
* A [ClassMirror] reflects a Dart language class.
|
|
*/
|
|
abstract class ClassMirror implements TypeMirror, ObjectMirror {
|
|
/**
|
|
* A mirror on the superclass on the reflectee.
|
|
*
|
|
* If this type is [:Object:], the superclass will be null.
|
|
*/
|
|
ClassMirror get superclass;
|
|
|
|
/**
|
|
* A list of mirrors on the superinterfaces of the reflectee.
|
|
*/
|
|
List<ClassMirror> get superinterfaces;
|
|
|
|
/**
|
|
* Is the reflectee abstract?
|
|
*/
|
|
bool get isAbstract;
|
|
|
|
/**
|
|
* Is the reflectee an enum?
|
|
*/
|
|
bool get isEnum;
|
|
|
|
/**
|
|
* Returns an immutable map of the declarations actually given in the class
|
|
* declaration.
|
|
*
|
|
* This map includes all regular methods, getters, setters, fields,
|
|
* constructors and type variables actually declared in the class. Both
|
|
* static and instance members are included, but no inherited members are
|
|
* included. The map is keyed by the simple names of the declarations.
|
|
*
|
|
* This does not include inherited members.
|
|
*/
|
|
Map<Symbol, DeclarationMirror> get declarations;
|
|
|
|
/**
|
|
* Returns a map of the methods, getters and setters of an instance of the
|
|
* class.
|
|
*
|
|
* The intent is to capture those members that constitute the API of an
|
|
* instance. Hence fields are not included, but the getters and setters
|
|
* implicitly introduced by fields are included. The map includes methods,
|
|
* getters and setters that are inherited as well as those introduced by the
|
|
* class itself.
|
|
*
|
|
* The map is keyed by the simple names of the members.
|
|
*/
|
|
Map<Symbol, MethodMirror> get instanceMembers;
|
|
|
|
/**
|
|
* Returns a map of the static methods, getters and setters of the class.
|
|
*
|
|
* The intent is to capture those members that constitute the API of a class.
|
|
* Hence fields are not included, but the getters and setters implicitly
|
|
* introduced by fields are included.
|
|
*
|
|
* The map is keyed by the simple names of the members.
|
|
*/
|
|
Map<Symbol, MethodMirror> get staticMembers;
|
|
|
|
|
|
/**
|
|
* The mixin of this class.
|
|
*
|
|
* If this class is the result of a mixin application of the form S with M,
|
|
* returns a class mirror on M. Otherwise returns a class mirror on
|
|
* [reflectee].
|
|
*/
|
|
ClassMirror get mixin;
|
|
|
|
// TODO(ahe): What about:
|
|
// /// Finds the instance member named [name] declared or inherited in the
|
|
// /// reflected class.
|
|
// DeclarationMirror instanceLookup(Symbol name);
|
|
|
|
/**
|
|
* 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, the effect is
|
|
* the same as if a non-reflective compilation error had been encountered.
|
|
* * If evaluating the expression throws an exception *e* (that it does not
|
|
* catch), this method throws *e*.
|
|
*/
|
|
InstanceMirror newInstance(Symbol constructorName,
|
|
List positionalArguments,
|
|
[Map<Symbol,dynamic> namedArguments]);
|
|
|
|
/**
|
|
* Whether this mirror is equal to [other].
|
|
*
|
|
* 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.
|
|
*/
|
|
bool operator == (other);
|
|
|
|
/**
|
|
* Returns whether the class denoted by the receiver is a subclass of the
|
|
* class denoted by the argument.
|
|
*
|
|
* Note that the subclass relationship is reflexive.
|
|
*/
|
|
bool isSubclassOf(ClassMirror other);
|
|
}
|
|
|
|
/**
|
|
* A [FunctionTypeMirror] represents the type of a function in the
|
|
* Dart language.
|
|
*/
|
|
abstract class FunctionTypeMirror implements ClassMirror {
|
|
/**
|
|
* Returns the return type of the reflectee.
|
|
*/
|
|
TypeMirror get returnType;
|
|
|
|
/**
|
|
* Returns a list of the parameter types of the reflectee.
|
|
*/
|
|
List<ParameterMirror> get parameters;
|
|
|
|
/**
|
|
* A mirror on the [:call:] method for the reflectee.
|
|
*/
|
|
// This is only here because in the past the VM did not implement a call
|
|
// method on closures.
|
|
MethodMirror get callMethod;
|
|
}
|
|
|
|
/**
|
|
* A [TypeVariableMirror] represents a type parameter of a generic type.
|
|
*/
|
|
abstract class TypeVariableMirror extends TypeMirror {
|
|
/**
|
|
* A mirror on the type that is the upper bound of this type variable.
|
|
*/
|
|
TypeMirror get upperBound;
|
|
|
|
/**
|
|
* Is the reflectee static?
|
|
*
|
|
* For the purposes of the mirrors library, type variables are considered
|
|
* non-static.
|
|
*/
|
|
bool get isStatic;
|
|
|
|
/**
|
|
* Whether [other] is a [TypeVariableMirror] on the same type variable as this
|
|
* mirror.
|
|
*
|
|
* 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:].
|
|
*/
|
|
bool operator == (other);
|
|
}
|
|
|
|
/**
|
|
* A [TypedefMirror] represents a typedef in a Dart language program.
|
|
*/
|
|
abstract class TypedefMirror implements TypeMirror {
|
|
/**
|
|
* The defining type for this typedef.
|
|
*
|
|
* If the type referred to by the reflectee is a function type *F*, the
|
|
* result will be [:FunctionTypeMirror:] reflecting *F* which is abstract
|
|
* and has an abstract method [:call:] whose signature corresponds to *F*.
|
|
* For instance [:void f(int):] is the referent for [:typedef void f(int):].
|
|
*/
|
|
FunctionTypeMirror get referent;
|
|
}
|
|
|
|
/**
|
|
* A [MethodMirror] reflects a Dart language function, method,
|
|
* constructor, getter, or setter.
|
|
*/
|
|
abstract class MethodMirror implements DeclarationMirror {
|
|
/**
|
|
* A mirror on the return type for the reflectee.
|
|
*/
|
|
TypeMirror get returnType;
|
|
|
|
/**
|
|
* The source code for the reflectee, if available. Otherwise null.
|
|
*/
|
|
String get source;
|
|
|
|
/**
|
|
* A list of mirrors on the parameters for the reflectee.
|
|
*/
|
|
List<ParameterMirror> get parameters;
|
|
|
|
/**
|
|
* A function is considered non-static iff it is permited to refer to 'this'.
|
|
*
|
|
* Note that generative constructors are considered non-static, whereas
|
|
* factory constructors are considered static.
|
|
*/
|
|
bool get isStatic;
|
|
|
|
/**
|
|
* Is the reflectee abstract?
|
|
*/
|
|
bool get isAbstract;
|
|
|
|
/**
|
|
* Returns true if the reflectee is synthetic, and returns false otherwise.
|
|
*
|
|
* A reflectee is synthetic if it is a getter or setter implicitly introduced
|
|
* for a field or Type, or if it is a constructor that was implicitly
|
|
* introduced as a default constructor or as part of a mixin application.
|
|
*/
|
|
bool get isSynthetic;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
bool get isRegularMethod;
|
|
|
|
/**
|
|
* Is the reflectee an operator?
|
|
*/
|
|
bool get isOperator;
|
|
|
|
/**
|
|
* Is the reflectee a getter?
|
|
*/
|
|
bool get isGetter;
|
|
|
|
/**
|
|
* Is the reflectee a setter?
|
|
*/
|
|
bool get isSetter;
|
|
|
|
/**
|
|
* Is the reflectee a constructor?
|
|
*/
|
|
bool get isConstructor;
|
|
|
|
/**
|
|
* 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:].
|
|
*/
|
|
Symbol get constructorName;
|
|
|
|
/**
|
|
* Is the reflectee a const constructor?
|
|
*/
|
|
bool get isConstConstructor;
|
|
|
|
/**
|
|
* Is the reflectee a generative constructor?
|
|
*/
|
|
bool get isGenerativeConstructor;
|
|
|
|
/**
|
|
* Is the reflectee a redirecting constructor?
|
|
*/
|
|
bool get isRedirectingConstructor;
|
|
|
|
/**
|
|
* Is the reflectee a factory constructor?
|
|
*/
|
|
bool get isFactoryConstructor;
|
|
|
|
/**
|
|
* Whether 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:].
|
|
*/
|
|
bool operator == (other);
|
|
}
|
|
|
|
/**
|
|
* A [VariableMirror] reflects a Dart language variable declaration.
|
|
*/
|
|
abstract class VariableMirror implements DeclarationMirror {
|
|
/**
|
|
* Returns a mirror on the type of the reflectee.
|
|
*/
|
|
TypeMirror get type;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
bool get isStatic;
|
|
|
|
/**
|
|
* Returns [:true:] if the reflectee is a final variable.
|
|
* Otherwise returns [:false:].
|
|
*/
|
|
bool get isFinal;
|
|
|
|
/**
|
|
* Returns [:true:] if the reflectee is declared [:const:].
|
|
* Otherwise returns [:false:].
|
|
*/
|
|
bool get isConst;
|
|
|
|
/**
|
|
* Whether 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:].
|
|
*/
|
|
bool operator == (other);
|
|
}
|
|
|
|
/**
|
|
* A [ParameterMirror] reflects a Dart formal parameter declaration.
|
|
*/
|
|
abstract class ParameterMirror implements VariableMirror {
|
|
/**
|
|
* A mirror on the type of this parameter.
|
|
*/
|
|
TypeMirror get type;
|
|
|
|
/**
|
|
* Returns [:true:] if the reflectee is an optional parameter.
|
|
* Otherwise returns [:false:].
|
|
*/
|
|
bool get isOptional;
|
|
|
|
/**
|
|
* Returns [:true:] if the reflectee is a named parameter.
|
|
* Otherwise returns [:false:].
|
|
*/
|
|
bool get isNamed;
|
|
|
|
/**
|
|
* Returns [:true:] if the reflectee has explicitly declared a default value.
|
|
* Otherwise returns [:false:].
|
|
*/
|
|
bool get hasDefaultValue;
|
|
|
|
/**
|
|
* Returns the default value of an optional parameter.
|
|
*
|
|
* Returns an [InstanceMirror] on the (compile-time constant)
|
|
* default value for an optional parameter.
|
|
* If no default value is declared, it defaults to `null`
|
|
* and a mirror of `null` is returned.
|
|
*
|
|
* Returns `null` for a required parameter.
|
|
*/
|
|
InstanceMirror get defaultValue;
|
|
}
|
|
|
|
/**
|
|
* A [SourceLocation] describes the span of an entity in Dart source code.
|
|
*/
|
|
abstract class SourceLocation {
|
|
/**
|
|
* The 1-based line number for this source location.
|
|
*
|
|
* A value of 0 means that the line number is unknown.
|
|
*/
|
|
int get line;
|
|
|
|
/**
|
|
* The 1-based column number for this source location.
|
|
*
|
|
* A value of 0 means that the column number is unknown.
|
|
*/
|
|
int get column;
|
|
|
|
/**
|
|
* Returns the URI where the source originated.
|
|
*/
|
|
Uri get sourceUri;
|
|
}
|
|
|
|
/**
|
|
* Class used for encoding comments as metadata annotations.
|
|
*/
|
|
class Comment {
|
|
/**
|
|
* The comment text as written in the source text.
|
|
*/
|
|
final String text;
|
|
|
|
/**
|
|
* The comment text without the start, end, and padding text.
|
|
*
|
|
* For example, if [text] is [: /** Comment text. */ :] then the [trimmedText]
|
|
* is [: Comment text. :].
|
|
*/
|
|
final String trimmedText;
|
|
|
|
/**
|
|
* Is [:true:] if this comment is a documentation comment.
|
|
*
|
|
* That is, that the comment is either enclosed in [: /** ... */ :] or starts
|
|
* with [: /// :].
|
|
*/
|
|
final bool isDocComment;
|
|
|
|
const Comment(this.text, this.trimmedText, this.isDocComment);
|
|
}
|
|
|
|
/**
|
|
* Annotation describing how "dart:mirrors" is used (EXPERIMENTAL).
|
|
*
|
|
* 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')
|
|
* import 'dart:mirrors';
|
|
*
|
|
* class Foo {
|
|
* noSuchMethod(Invocation invocation) {
|
|
* print(MirrorSystem.getName(invocation.memberName));
|
|
* }
|
|
* }
|
|
*
|
|
* main() {
|
|
* new Foo().foo(); // Prints "foo".
|
|
* new Foo().bar(); // Might print an arbitrary (mangled) name, "bar".
|
|
* }
|
|
*
|
|
* For a detailed description of the parameters to the [MirrorsUsed] constructor
|
|
* see the comments for [symbols], [targets], [metaTargets] and [override].
|
|
*
|
|
* An import of `dart:mirrors` may have multiple [MirrorsUsed] annotations. This
|
|
* is particularly helpful to specify overrides for specific libraries. For
|
|
* example:
|
|
*
|
|
* @MirrorsUsed(targets: 'foo.Bar', override: 'foo')
|
|
* @MirrorsUsed(targets: 'Bar')
|
|
* import 'dart:mirrors';
|
|
*
|
|
* will ensure that the target `Bar` from the current library and from library
|
|
* `foo` is available for reflection. See also [override].
|
|
*/
|
|
class MirrorsUsed {
|
|
// Note: the fields of this class are untyped. This is because the most
|
|
// convenient way to specify symbols today is using a single string. In
|
|
// some cases, a const list of classes might be convenient. Some
|
|
// might prefer to use a const list of symbols.
|
|
|
|
/**
|
|
* 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:
|
|
*
|
|
* Dart2js currently supports the following formats to specify symbols:
|
|
*
|
|
* * A constant [List] of [String] constants representing symbol names,
|
|
* e.g., `const ['foo', 'bar']`.
|
|
* * A single [String] constant whose value is a comma-separated list of
|
|
* symbol names, e.g., `"foo, bar"`.
|
|
*
|
|
* Specifying the `symbols` field turns off the following warnings emitted by
|
|
* dart2js:
|
|
*
|
|
* * Using "MirrorSystem.getName" may result in larger output.
|
|
* * Using "new Symbol" may result in larger output.
|
|
*
|
|
* For example, if you're using [noSuchMethod] to interact with a database,
|
|
* extract all the possible column names and include them in this list.
|
|
* Similarly, if you're using [noSuchMethod] to interact with another
|
|
* language (JavaScript, for example) extract all the identifiers from the
|
|
* API you use and include them in this list.
|
|
*
|
|
* Note that specifying a symbol only ensures that the symbol will be
|
|
* available under that name at runtime. It does not mark targets with
|
|
* that name as available for reflection. See [targets] and [metaTargets]
|
|
* for that purpose.
|
|
*/
|
|
final symbols;
|
|
|
|
/**
|
|
* 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, a target is a library, a class, a method or a field.
|
|
*
|
|
* Dart2js currently supports the following formats to specify targets:
|
|
*
|
|
* * A constant [List] containing [String] constants representing (qualified)
|
|
* names of targets and Dart types.
|
|
* * A single [String] constant whose value is a comma-separated list of
|
|
* (qualified) names.
|
|
* * A single Dart type.
|
|
*
|
|
* A (qualified) name is resolved to a target as follows:
|
|
*
|
|
* 1. If the qualified name matches a library name, the matching library is
|
|
* the target.
|
|
* 2. Else, find the longest prefix of the name such that the prefix ends
|
|
* just before a `.` and is a library name.
|
|
* 3. Use that library as current scope. If no matching prefix was found, use
|
|
* the current library, i.e., the library where the [MirrorsUsed]
|
|
* annotation was placed.
|
|
* 4. Split the remaining suffix (the entire name if no library name was
|
|
* found in step 3) into a list of [String] using `.` as a
|
|
* separator.
|
|
* 5. Select all targets in the current scope whose name matches a [String]
|
|
* from the list.
|
|
*
|
|
* For example:
|
|
*
|
|
* library my.library.one;
|
|
*
|
|
* class A {
|
|
* var aField;
|
|
* }
|
|
*
|
|
* library main;
|
|
*
|
|
* @MirrorsUsed(targets: "my.library.one.A.aField")
|
|
* import "dart:mirrors";
|
|
*
|
|
* The [MirrorsUsed] annotation specifies `A` and `aField` from library
|
|
* `my.library.one` as targets. This will mark the class `A` as a reflective
|
|
* target. The target specification for `aField` has no effect, as there is
|
|
* no target in `my.library.one` with that name.
|
|
*
|
|
* Note that everything within a target also is available for reflection.
|
|
* So, if a library is specified as target, all classes in that library
|
|
* become targets for reflection. Likewise, if a class is a target, all
|
|
* its methods and fields become targets for reflection. As a consequence,
|
|
* `aField` in the above example is also a reflective target.
|
|
*
|
|
*/
|
|
final targets;
|
|
|
|
/**
|
|
* A list of classes that when used as metadata indicates a reflective
|
|
* target. See also [targets].
|
|
*
|
|
* The following text is non-normative:
|
|
*
|
|
* The format for specifying the list of classes is the same as used for
|
|
* specifying [targets]. However, as a library cannot be used as a metadata
|
|
* annotation in Dart, adding a library to the list of [metaTargets] has no
|
|
* effect. In particular, adding a library to [metaTargets] does not make
|
|
* the library's classes valid metadata annotations to enable reflection.
|
|
*
|
|
* If an instance of a class specified in [metaTargets] is used as
|
|
* metadata annotation on a library, class, field or method, that library,
|
|
* class, field or method is added to the set of targets for reflection.
|
|
*
|
|
* Example usage:
|
|
*
|
|
* library example;
|
|
* @MirrorsUsed(metaTargets: "example.Reflectable")
|
|
* import "dart:mirrors";
|
|
*
|
|
* class Reflectable {
|
|
* const Reflectable();
|
|
* }
|
|
*
|
|
* class Foo {
|
|
* @Reflectable()
|
|
* reflectableMethod() { ... }
|
|
*
|
|
* nonReflectableMethod() { ... }
|
|
* }
|
|
*
|
|
* In the above example. `reflectableMethod` is marked as reflectable by
|
|
* using the `Reflectable` class, which in turn is specified in the
|
|
* [metaTargets] annotation.
|
|
*
|
|
* The method `nonReflectableMethod` lacks a metadata annotation and thus
|
|
* will not be reflectable at runtime.
|
|
*/
|
|
final metaTargets;
|
|
|
|
/**
|
|
* 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 following text is non-normative:
|
|
*
|
|
* Dart2js currently supports the following formats to specify libraries:
|
|
*
|
|
* * A constant [List] containing [String] constants representing names of
|
|
* libraries.
|
|
* * A single [String] constant whose value is a comma-separated list of
|
|
* library names.
|
|
*
|
|
* Conceptually, a [MirrorsUsed] annotation with [override] has the same
|
|
* effect as placing the annotation directly on the import of `dart:mirrors`
|
|
* in each of the referenced libraries. Thus, if the library had no
|
|
* [MirrorsUsed] annotation before, its unconditional import of
|
|
* `dart:mirrors` is overridden by an annotated import.
|
|
*
|
|
* Note that, like multiple explicit [MirrorsUsed] annotations, using
|
|
* override on a library with an existing [MirrorsUsed] annotation is
|
|
* additive. That is, the overall set of reflective targets is the union
|
|
* of the reflective targets that arise from the original and the
|
|
* overriding [MirrorsUsed] annotations.
|
|
*
|
|
* The use of [override] is only meaningful for libraries that have an
|
|
* import of `dart:mirrors` without annotation because otherwise it would
|
|
* work exactly the same way without the [override] parameter.
|
|
*
|
|
* While the annotation will apply to the given target libraries, the
|
|
* [symbols], [targets] and [metaTargets] are still evaluated in the
|
|
* scope of the annotation. Thus, to select a target from library `foo`,
|
|
* a qualified name has to be used or, if the target is visible in the
|
|
* current scope, its type may be referenced.
|
|
*
|
|
* For example, the following code marks all targets in the library `foo`
|
|
* as reflectable that have a metadata annotation using the `Reflectable`
|
|
* class from the same library.
|
|
*
|
|
* @MirrorsUsed(metaTargets: "foo.Reflectable", override: "foo")
|
|
*
|
|
* However, the following code would require the use of the `Reflectable`
|
|
* class from the current library, instead.
|
|
*
|
|
* @MirrorsUsed(metaTargets: "Reflectable", override: "foo")
|
|
*
|
|
*/
|
|
final override;
|
|
|
|
/**
|
|
* See the documentation for [MirrorsUsed.symbols], [MirrorsUsed.targets],
|
|
* [MirrorsUsed.metaTargets] and [MirrorsUsed.override] for documentation
|
|
* of the parameters.
|
|
*/
|
|
const MirrorsUsed(
|
|
{this.symbols, this.targets, this.metaTargets, this.override});
|
|
}
|