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

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