// 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 only supported by the Dart VM and
 * only available on some platforms.
 *
 * {@category VM}
 */
library dart.mirrors;

import 'dart:async' show Future;
import "dart:_internal" show Since;

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

  /**
   * A mirror on the [:Never:] type.
   */
  @Since("2.8")
  TypeMirror get neverType;

  /**
   * 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(dynamic 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 ==(Object 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*.
   */
  InstanceMirror invoke(Symbol memberName, List<dynamic> positionalArguments,
      [Map<Symbol, dynamic> namedArguments = const <Symbol, dynamic>{}]);

  /**
   * 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*.
   */
  InstanceMirror setField(Symbol fieldName, dynamic 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.
   */
  dynamic 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 ==(Object 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<dynamic> positionalArguments,
      [Map<Symbol, dynamic> namedArguments = const <Symbol, dynamic>{}]);
}

/**
 * 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 ==(Object 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;

  /**
   * 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<dynamic> positionalArguments,
      [Map<Symbol, dynamic> namedArguments = const <Symbol, dynamic>{}]);

  /**
   * 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 ==(Object 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 ==(Object 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;

  /**
   * Is the reflectee an extension method?
   */
  bool get isExtensionMember;

  /**
   * 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 ==(Object 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;

  /**
   * Is the reflectee an extension member?
   */
  bool get isExtensionMember;

  /**
   * 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 ==(Object 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});
}
