// 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.
 *
 * {@category VM}
 */
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.
   */
  external LibraryMirror findLibrary(Symbol 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].
 *
 * Optionally takes a list of [typeArguments] for generic classes. If the list
 * is provided, then the [key] must be a generic class type, and the number of
 * the provided type arguments must be equal to the number of type variables
 * declared by the class.
 *
 * 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, [List<Type> typeArguments]);

/**
 * 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);

  /**
   * Loads the library at the given uri into this isolate.
   *
   * WARNING: You are strongly encouraged to use Isolate.spawnUri instead when
   * possible. IsolateMirror.loadUri should only be used when synchronous
   * communication or shared state with dynamically loaded code is needed.
   *
   * If a library with the same canonicalized uri has already been loaded,
   * the existing library will be returned. (The isolate will not load a new
   * copy of the library.)
   *
   * This behavior is similar to the behavior of an import statement that
   * appears in the root library, except that the import scope of the root
   * library is not changed.
   */
  Future<LibraryMirror> loadUri(Uri uri);
}

/**
 * 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 the reflectee of this [ObjectMirror].
   *
   * Equivalent to
   *
   *     if (invocation.isGetter) {
   *       return this.getField(invocation.memberName).reflectee;
   *     } else if (invocation.isSetter) {
   *       return this.setField(invocation.memberName,
   *                            invocation.positionalArguments[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
   * the 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].
 */
@Deprecated("No longer has any effect. Will be removed in a later release.")
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});
}
