// Copyright (c) 2012, 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.

// VM-specific implementation of the dart:mirrors library.

import "dart:collection" show UnmodifiableListView, UnmodifiableMapView;
import "dart:_internal" as internal;

var _dirty = false;
final _emptyList = new UnmodifiableListView([]);

class _InternalMirrorError {
  final String _msg;
  const _InternalMirrorError(this._msg);
  String toString() => _msg;
}

String _n(Symbol symbol) => internal.Symbol.getName(symbol);

Symbol _s(String name) {
  if (name == null) return null;
  return new internal.Symbol.unvalidated(name);
}

Symbol _computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
  if (owner == null) return simpleName;
  return _s('${_n(owner.qualifiedName)}.${_n(simpleName)}');
}

String _makeSignatureString(
    TypeMirror returnType, List<ParameterMirror> parameters) {
  StringBuffer buf = new StringBuffer();
  buf.write('(');
  bool found_optional_positional = false;
  bool found_optional_named = false;

  for (int i = 0; i < parameters.length; i++) {
    var param = parameters[i];
    if (param.isOptional && param.isNamed && !found_optional_named) {
      buf.write('{');
      found_optional_named = true;
    }
    if (param.isOptional && !param.isNamed && !found_optional_positional) {
      buf.write('[');
      found_optional_positional = true;
    }
    if (param.isNamed) {
      buf.write(_n(param.simpleName));
      buf.write(': ');
    }
    buf.write(_n(param.type.qualifiedName));
    if (i < (parameters.length - 1)) {
      buf.write(', ');
    }
  }
  if (found_optional_named) {
    buf.write('}');
  }
  if (found_optional_positional) {
    buf.write(']');
  }
  buf.write(') -> ');
  buf.write(_n(returnType.qualifiedName));
  return buf.toString();
}

SourceLocation _location(reflectee) native "DeclarationMirror_location";

List _metadata(reflectee) native 'DeclarationMirror_metadata';

bool _subtypeTest(Type a, Type b) native 'TypeMirror_subtypeTest';

class _AccessorCacheAssociation {
  String key;
  Function value;
  bool usedSinceGrowth = true;
  _AccessorCacheAssociation(this.key, this.value);
}

/**
 * A map that will grow as associations are added but will prefer to evict
 * associations that have not been used since the last growth when needing to
 * grow again. Implemented as an open addressing hash table.
 */
class _AccessorCache {
  List table;
  int shift;
  int mask;
  int capacity; // Max number of associations before we start evicting/growing.
  int size = 0; // Current number of associations.

  /**
   * Create a cache whose capacity is 75% of 2^shift.
   */
  _AccessorCache.withInitialShift(int shift) {
    // The scheme used here for handling collisions relies on there always
    // being at least one empty slot.
    if (shift < 1) throw new Exception("_AccessorCache requires a shift >= 1");
    initWithShift(shift);
  }

  void initWithShift(int shift) {
    this.shift = shift;
    this.mask = (1 << shift) - 1;
    this.capacity = (1 << shift) * 3 ~/ 4;
    this.table = new List(1 << shift);
    assert(table.length > capacity);
  }

  int scanFor(String key) {
    var start = key.hashCode & mask;
    var index = start;
    do {
      var assoc = table[index];
      if (null == assoc || assoc.key == key) {
        return index;
      }
      index = (index + 1) & mask;
    } while (index != start);
    // Should never happen because we start evicting associations before the
    // table is full.
    throw new Exception("Internal error: _AccessorCache table full");
  }

  int scanForEmpty(String key) {
    var start = key.hashCode & mask;
    var index = start;
    do {
      if (null == table[index]) {
        return index;
      }
      index = (index + 1) & mask;
    } while (index != start);
    // Should never happen because we start evicting associations before the
    // table is full.
    throw new Exception("Internal error: _AccessorCache table full");
  }

  void fixCollisionsAfter(int start) {
    var assoc;
    var index = (start + 1) & mask;
    while (null != (assoc = table[index])) {
      var newIndex = scanFor(assoc.key);
      if (newIndex != index) {
        assert(table[newIndex] == null);
        table[newIndex] = assoc;
        table[index] = null;
      }
      index = (index + 1) & mask;
    }
  }

  void grow() {
    var oldTable = table;

    initWithShift(shift + 1);

    for (int oldIndex = 0; oldIndex < oldTable.length; oldIndex++) {
      var assoc = oldTable[oldIndex];
      if (assoc != null) {
        var newIndex = scanForEmpty(assoc.key);
        assoc.usedSinceGrowth = false;
        table[newIndex] = assoc;
      }
    }
  }

  void tryToShrinkOtherwiseGrow() {
    // Remove any associations not accessed since the last growth. If we are
    // unable to free any slots, grow.
    bool needToGrow = true;
    for (int i = 0; i < table.length; i++) {
      var assoc = table[i];
      if (null != assoc && (!assoc.usedSinceGrowth || null == assoc.value)) {
        table[i] = null;
        size--;
        fixCollisionsAfter(i);
        needToGrow = false;
      }
    }
    if (needToGrow) grow();
  }

  operator []=(String key, Function value) {
    int index = scanFor(key);
    var assoc = table[index];
    if (null != assoc) {
      // Existing key, replace value.
      assert(assoc.key == key);
      assoc.value = value;
      assoc.usedSinceGrowth = true;
    } else {
      // New key.
      var newAssoc = new _AccessorCacheAssociation(key, value);
      if (size == capacity) {
        // No free slots.
        tryToShrinkOtherwiseGrow();
        index = scanFor(key);
        assert(table[index] == null);
      }
      table[index] = newAssoc;
      size++;
    }
  }

  Function operator [](String key) {
    var index = scanFor(key);
    var assoc = table[index];
    if (null == assoc) return null;
    assoc.usedSinceGrowth = true;
    return assoc.value;
  }
}

class _LocalMirrorSystem extends MirrorSystem {
  final TypeMirror dynamicType = new _SpecialTypeMirror('dynamic');
  final TypeMirror voidType = new _SpecialTypeMirror('void');

  var _libraries;
  Map<Uri, LibraryMirror> get libraries {
    if ((_libraries == null) || _dirty) {
      _libraries = new Map<Uri, LibraryMirror>.fromIterable(_computeLibraries(),
          key: (e) => e.uri);
      _dirty = false;
    }
    return _libraries;
  }

  static _computeLibraries() native "MirrorSystem_libraries";

  var _isolate;
  IsolateMirror get isolate {
    if (_isolate == null) {
      _isolate = _computeIsolate();
    }
    return _isolate;
  }

  static _computeIsolate() native "MirrorSystem_isolate";

  String toString() => "MirrorSystem for isolate '${isolate.debugName}'";
}

class _SourceLocation implements SourceLocation {
  _SourceLocation(uriString, this.line, this.column)
      : this.sourceUri = Uri.parse(uriString);

  // Line and column positions are 1-origin, or 0 if unknown.
  final int line;
  final int column;

  final Uri sourceUri;

  String toString() {
    return column == 0 ? "$sourceUri:$line" : "$sourceUri:$line:$column";
  }
}

abstract class _LocalMirror implements Mirror {}

class _LocalIsolateMirror extends _LocalMirror implements IsolateMirror {
  final String debugName;
  final LibraryMirror rootLibrary;

  _LocalIsolateMirror(this.debugName, this.rootLibrary);

  bool get isCurrent => true;

  String toString() => "IsolateMirror on '$debugName'";
}

class _SyntheticAccessor implements MethodMirror {
  final DeclarationMirror owner;
  final Symbol simpleName;
  final bool isGetter;
  final bool isStatic;
  final bool isTopLevel;
  final _target;

  _SyntheticAccessor(this.owner, this.simpleName, this.isGetter, this.isStatic,
      this.isTopLevel, this._target);

  bool get isSynthetic => true;
  bool get isRegularMethod => false;
  bool get isOperator => false;
  bool get isConstructor => false;
  bool get isConstConstructor => false;
  bool get isGenerativeConstructor => false;
  bool get isFactoryConstructor => false;
  bool get isExternal => false;
  bool get isRedirectingConstructor => false;
  bool get isAbstract => false;

  bool get isSetter => !isGetter;
  bool get isPrivate => _n(simpleName).startsWith('_');

  Symbol get qualifiedName => _computeQualifiedName(owner, simpleName);
  Symbol get constructorName => const Symbol('');

  TypeMirror get returnType => _target.type;
  List<ParameterMirror> get parameters {
    if (isGetter) return _emptyList;
    return new UnmodifiableListView(
        [new _SyntheticSetterParameter(this, this._target)]);
  }

  SourceLocation get location => null;
  List<InstanceMirror> get metadata => _emptyList;
  String get source => null;
}

class _SyntheticSetterParameter implements ParameterMirror {
  final DeclarationMirror owner;
  final VariableMirror _target;

  _SyntheticSetterParameter(this.owner, this._target);

  Symbol get simpleName => _target.simpleName;
  Symbol get qualifiedName => _computeQualifiedName(owner, simpleName);
  TypeMirror get type => _target.type;

  bool get isOptional => false;
  bool get isNamed => false;
  bool get isStatic => false;
  bool get isTopLevel => false;
  bool get isConst => false;
  bool get isFinal => true;
  bool get isPrivate => false;
  bool get hasDefaultValue => false;
  InstanceMirror get defaultValue => null;
  SourceLocation get location => null;
  List<InstanceMirror> get metadata => _emptyList;
}

abstract class _LocalObjectMirror extends _LocalMirror implements ObjectMirror {
  final _reflectee; // May be a MirrorReference or an ordinary object.

  _LocalObjectMirror(this._reflectee);

  InstanceMirror invoke(Symbol memberName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    int numPositionalArguments = positionalArguments.length;
    int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
    int numArguments = numPositionalArguments + numNamedArguments;
    List arguments = new List(numArguments);
    arguments.setRange(0, numPositionalArguments, positionalArguments);
    List names = new List(numNamedArguments);
    int argumentIndex = numPositionalArguments;
    int nameIndex = 0;
    if (numNamedArguments > 0) {
      namedArguments.forEach((name, value) {
        arguments[argumentIndex++] = value;
        names[nameIndex++] = _n(name);
      });
    }

    return reflect(this._invoke(_reflectee, _n(memberName), arguments, names));
  }

  InstanceMirror getField(Symbol memberName) {
    return reflect(this._invokeGetter(_reflectee, _n(memberName)));
  }

  InstanceMirror setField(Symbol memberName, Object value) {
    this._invokeSetter(_reflectee, _n(memberName), value);
    return reflect(value);
  }

  delegate(Invocation invocation) {
    if (invocation.isMethod) {
      return this
          .invoke(invocation.memberName, invocation.positionalArguments,
              invocation.namedArguments)
          .reflectee;
    }
    if (invocation.isGetter) {
      return this.getField(invocation.memberName).reflectee;
    }
    if (invocation.isSetter) {
      var unwrapped = _n(invocation.memberName);
      var withoutEqual = _s(unwrapped.substring(0, unwrapped.length - 1));
      var arg = invocation.positionalArguments[0];
      this.setField(withoutEqual, arg).reflectee;
      return arg;
    }
    throw "UNREACHABLE";
  }
}

class _LocalInstanceMirror extends _LocalObjectMirror
    implements InstanceMirror {
  _LocalInstanceMirror(reflectee) : super(reflectee);

  ClassMirror _type;
  ClassMirror get type {
    if (_type == null) {
      // Note it not safe to use reflectee.runtimeType because runtimeType may
      // be overridden.
      _type = reflectType(_computeType(reflectee));
    }
    return _type;
  }

  // LocalInstanceMirrors always reflect local instances
  bool get hasReflectee => true;

  get reflectee => _reflectee;

  String toString() => 'InstanceMirror on ${Error.safeToString(_reflectee)}';

  bool operator ==(other) {
    return other is _LocalInstanceMirror &&
        identical(_reflectee, other._reflectee);
  }

  int get hashCode {
    // Avoid hash collisions with the reflectee. This constant is in Smi range
    // and happens to be the inner padding from RFC 2104.
    return identityHashCode(_reflectee) ^ 0x36363636;
  }

  static var _getFieldClosures = new _AccessorCache.withInitialShift(4);
  static var _setFieldClosures = new _AccessorCache.withInitialShift(4);

  _createGetterClosure(unwrapped) {
    var atPosition = unwrapped.indexOf('@');
    if (atPosition == -1) {
      // Public symbol.
      return _eval('(x) => x.$unwrapped', null);
    } else {
      // Private symbol.
      var withoutKey = unwrapped.substring(0, atPosition);
      var privateKey = unwrapped.substring(atPosition);
      return _eval('(x) => x.$withoutKey', privateKey);
    }
  }

  _getFieldSlow(unwrapped) {
    // Slow path factored out to give the fast path a better chance at being
    // inlined.
    var result = reflect(_invokeGetter(_reflectee, unwrapped));
    // Wait until success to avoid creating closures for non-existent getters,
    // and defer the creation until the next getField invocation.
    // o.<operator> is not valid Dart and will cause a compilation error, so
    // don't attempt to generate such a closure.
    bool isOperator = _LocalMethodMirror._operators.contains(unwrapped);
    if (!isOperator) {
      _getFieldClosures[unwrapped] = (receiver) {
        var getterClosure = _createGetterClosure(unwrapped);
        _getFieldClosures[unwrapped] = getterClosure;
        return getterClosure(receiver);
      };
    }
    return result;
  }

  InstanceMirror getField(Symbol memberName) {
    var unwrapped = _n(memberName);
    var f = _getFieldClosures[unwrapped];
    return (f == null) ? _getFieldSlow(unwrapped) : reflect(f(_reflectee));
  }

  _createSetterClosure(unwrapped) {
    var atPosition = unwrapped.indexOf('@');
    if (atPosition == -1) {
      // Public symbol.
      return _eval('(x, v) => x.$unwrapped = v', null);
    } else {
      // Private symbol.
      var withoutKey = unwrapped.substring(0, atPosition);
      var privateKey = unwrapped.substring(atPosition);
      return _eval('(x, v) => x.$withoutKey = v', privateKey);
    }
  }

  _setFieldSlow(unwrapped, arg) {
    // Slow path factored out to give the fast path a better chance at being
    // inlined.
    _invokeSetter(_reflectee, unwrapped, arg);
    var result = reflect(arg);
    // Wait until success to avoid creating closures for non-existent setters.
    // and defer the creation until the next setField invocation.
    _setFieldClosures[unwrapped] = (receiver, argument) {
      var setterClosure = _createSetterClosure(unwrapped);
      _setFieldClosures[unwrapped] = setterClosure;
      return setterClosure(receiver, argument);
    };
    return result;
  }

  InstanceMirror setField(Symbol memberName, arg) {
    var unwrapped = _n(memberName);
    var f = _setFieldClosures[unwrapped];
    return (f == null)
        ? _setFieldSlow(unwrapped, arg)
        : reflect(f(_reflectee, arg));
  }

  static _eval(expression, privateKey)
      native "Mirrors_evalInLibraryWithPrivateKey";

  // Override to include the receiver in the arguments.
  InstanceMirror invoke(Symbol memberName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    int numPositionalArguments = positionalArguments.length + 1; // Receiver.
    int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
    int numArguments = numPositionalArguments + numNamedArguments;
    List arguments = new List(numArguments);
    arguments[0] = _reflectee; // Receiver.
    arguments.setRange(1, numPositionalArguments, positionalArguments);
    List names = new List(numNamedArguments);
    int argumentIndex = numPositionalArguments;
    int nameIndex = 0;
    if (numNamedArguments > 0) {
      namedArguments.forEach((name, value) {
        arguments[argumentIndex++] = value;
        names[nameIndex++] = _n(name);
      });
    }

    return reflect(this._invoke(_reflectee, _n(memberName), arguments, names));
  }

  _invoke(reflectee, functionName, arguments, argumentNames)
      native 'InstanceMirror_invoke';

  _invokeGetter(reflectee, getterName) native 'InstanceMirror_invokeGetter';

  _invokeSetter(reflectee, setterName, value)
      native 'InstanceMirror_invokeSetter';

  static _computeType(reflectee) native 'InstanceMirror_computeType';
}

class _LocalClosureMirror extends _LocalInstanceMirror
    implements ClosureMirror {
  _LocalClosureMirror(reflectee) : super(reflectee);

  MethodMirror _function;
  MethodMirror get function {
    if (_function == null) {
      _function = _computeFunction(reflectee);
    }
    return _function;
  }

  InstanceMirror apply(List<Object> positionalArguments,
      [Map<Symbol, Object> namedArguments]) {
    return this.invoke(#call, positionalArguments, namedArguments);
  }

  String toString() => "ClosureMirror on '${Error.safeToString(_reflectee)}'";

  static _computeFunction(reflectee) native 'ClosureMirror_function';
}

class _LocalClassMirror extends _LocalObjectMirror implements ClassMirror {
  final Type _reflectedType;
  Symbol _simpleName;
  DeclarationMirror _owner;
  final bool isAbstract;
  final bool _isGeneric;
  final bool _isMixinAlias;
  final bool _isGenericDeclaration;
  final bool isEnum;
  Type _instantiator;

  _LocalClassMirror(
      reflectee,
      reflectedType,
      String simpleName,
      this._owner,
      this.isAbstract,
      this._isGeneric,
      this._isMixinAlias,
      this._isGenericDeclaration,
      this.isEnum)
      : this._simpleName = _s(simpleName),
        this._reflectedType = reflectedType,
        this._instantiator = reflectedType,
        super(reflectee);

  bool get hasReflectedType => !_isGenericDeclaration;
  Type get reflectedType {
    if (!hasReflectedType) {
      throw new UnsupportedError(
          "Declarations of generics have no reflected type");
    }
    return _reflectedType;
  }

  Symbol get simpleName {
    // All but anonymous mixin applications have their name set at construction.
    if (_simpleName == null) {
      _simpleName = this._mixinApplicationName;
    }
    return _simpleName;
  }

  Symbol _qualifiedName = null;
  Symbol get qualifiedName {
    if (_qualifiedName == null) {
      _qualifiedName = _computeQualifiedName(owner, simpleName);
    }
    return _qualifiedName;
  }

  DeclarationMirror get owner {
    if (_owner == null) {
      var uri = _LocalClassMirror._libraryUri(_reflectee);
      _owner = currentMirrorSystem().libraries[Uri.parse(uri)];
    }
    return _owner;
  }

  bool get isPrivate => _n(simpleName).startsWith('_');

  bool get isTopLevel => true;

  SourceLocation get location {
    return _location(_reflectee);
  }

  ClassMirror _trueSuperclassField;
  ClassMirror get _trueSuperclass {
    if (_trueSuperclassField == null) {
      Type supertype = isOriginalDeclaration
          ? _supertype(_reflectedType)
          : _supertypeInstantiated(_reflectedType);
      if (supertype == null) {
        // Object has no superclass.
        return null;
      }
      _trueSuperclassField = reflectType(supertype);
      _trueSuperclassField._instantiator = _instantiator;
    }
    return _trueSuperclassField;
  }

  ClassMirror get superclass {
    return _isMixinAlias ? _trueSuperclass._trueSuperclass : _trueSuperclass;
  }

  var _superinterfaces;
  List<ClassMirror> get superinterfaces {
    if (_superinterfaces == null) {
      _superinterfaces = isOriginalDeclaration
          ? _nativeInterfaces(_reflectedType)
          : _nativeInterfacesInstantiated(_reflectedType);
      _superinterfaces =
          new UnmodifiableListView(_superinterfaces.map(reflectType));
    }
    return _superinterfaces;
  }

  get _mixinApplicationName {
    var mixins = new List<ClassMirror>();
    var klass = this;
    while (_nativeMixin(klass._reflectedType) != null) {
      mixins.add(klass.mixin);
      klass = klass.superclass;
    }
    return _s(_n(klass.qualifiedName) +
        ' with ' +
        mixins.reversed.map((m) => _n(m.qualifiedName)).join(', '));
  }

  var _mixin;
  ClassMirror get mixin {
    if (_mixin == null) {
      if (_isMixinAlias) {
        Type mixinType = _nativeMixinInstantiated(
            _trueSuperclass._reflectedType, _instantiator);
        _mixin = reflectType(mixinType);
      } else {
        Type mixinType =
            _nativeMixinInstantiated(_reflectedType, _instantiator);
        if (mixinType == null) {
          // The reflectee is not a mixin application.
          _mixin = this;
        } else {
          _mixin = reflectType(mixinType);
        }
      }
    }
    return _mixin;
  }

  var _cachedStaticMembers;
  Map<Symbol, MethodMirror> get staticMembers {
    if (_cachedStaticMembers == null) {
      var result = new Map<Symbol, MethodMirror>();
      declarations.values.forEach((decl) {
        if (decl is MethodMirror && decl.isStatic && !decl.isConstructor) {
          result[decl.simpleName] = decl;
        }
        if (decl is VariableMirror && decl.isStatic) {
          var getterName = decl.simpleName;
          result[getterName] =
              new _SyntheticAccessor(this, getterName, true, true, false, decl);
          if (!decl.isFinal) {
            var setterName = _asSetter(decl.simpleName, this.owner);
            result[setterName] = new _SyntheticAccessor(
                this, setterName, false, true, false, decl);
          }
        }
      });
      _cachedStaticMembers =
          new UnmodifiableMapView<Symbol, MethodMirror>(result);
    }
    return _cachedStaticMembers;
  }

  var _cachedInstanceMembers;
  Map<Symbol, MethodMirror> get instanceMembers {
    if (_cachedInstanceMembers == null) {
      var result = new Map<Symbol, MethodMirror>();
      if (superclass != null) {
        result.addAll(superclass.instanceMembers);
      }
      declarations.values.forEach((decl) {
        if (decl is MethodMirror &&
            !decl.isStatic &&
            !decl.isConstructor &&
            !decl.isAbstract) {
          result[decl.simpleName] = decl;
        }
        if (decl is VariableMirror && !decl.isStatic) {
          var getterName = decl.simpleName;
          result[getterName] = new _SyntheticAccessor(
              this, getterName, true, false, false, decl);
          if (!decl.isFinal) {
            var setterName = _asSetter(decl.simpleName, this.owner);
            result[setterName] = new _SyntheticAccessor(
                this, setterName, false, false, false, decl);
          }
        }
      });
      _cachedInstanceMembers =
          new UnmodifiableMapView<Symbol, MethodMirror>(result);
    }
    return _cachedInstanceMembers;
  }

  Map<Symbol, DeclarationMirror> _declarations;
  Map<Symbol, DeclarationMirror> get declarations {
    if (_declarations != null) return _declarations;

    var decls = new Map<Symbol, DeclarationMirror>();

    var whoseMembers = _isMixinAlias ? _trueSuperclass : this;
    var members =
        mixin._computeMembers(_instantiator, whoseMembers.mixin._reflectee);
    for (var member in members) {
      decls[member.simpleName] = member;
    }

    var constructors = _computeConstructors(_instantiator, _reflectee);
    var stringName = _n(simpleName);
    for (var constructor in constructors) {
      constructor._patchConstructorName(stringName);
      decls[constructor.simpleName] = constructor;
    }

    for (var typeVariable in typeVariables) {
      decls[typeVariable.simpleName] = typeVariable;
    }

    return _declarations =
        new UnmodifiableMapView<Symbol, DeclarationMirror>(decls);
  }

  bool get _isAnonymousMixinApplication {
    if (_isMixinAlias) return false; // Named mixin application.
    if (mixin == this) return false; // Not a mixin application.
    return true;
  }

  List<TypeVariableMirror> _typeVariables = null;
  List<TypeVariableMirror> get typeVariables {
    if (_typeVariables == null) {
      if (_isAnonymousMixinApplication) return _typeVariables = _emptyList;
      _typeVariables = new List<TypeVariableMirror>();

      List params = _ClassMirror_type_variables(_reflectee);
      ClassMirror owner = originalDeclaration;
      var mirror;
      for (var i = 0; i < params.length; i += 2) {
        mirror = new _LocalTypeVariableMirror(params[i + 1], params[i], owner);
        _typeVariables.add(mirror);
      }
      _typeVariables = new UnmodifiableListView(_typeVariables);
    }
    return _typeVariables;
  }

  List<TypeMirror> _typeArguments = null;
  List<TypeMirror> get typeArguments {
    if (_typeArguments == null) {
      if (_isGenericDeclaration || _isAnonymousMixinApplication) {
        _typeArguments = _emptyList;
      } else {
        _typeArguments =
            new UnmodifiableListView(_computeTypeArguments(_reflectedType));
      }
    }
    return _typeArguments;
  }

  bool get isOriginalDeclaration => !_isGeneric || _isGenericDeclaration;

  ClassMirror get originalDeclaration {
    if (isOriginalDeclaration) {
      return this;
    } else {
      return reflectClass(_reflectedType);
    }
  }

  String toString() => "ClassMirror on '${MirrorSystem.getName(simpleName)}'";

  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    // Native code will add the 1 or 2 implicit arguments depending on whether
    // we end up invoking a factory or constructor respectively.
    int numPositionalArguments = positionalArguments.length;
    int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
    int numArguments = numPositionalArguments + numNamedArguments;
    List arguments = new List(numArguments);
    arguments.setRange(0, numPositionalArguments, positionalArguments);
    List names = new List(numNamedArguments);
    int argumentIndex = numPositionalArguments;
    int nameIndex = 0;
    if (numNamedArguments > 0) {
      namedArguments.forEach((name, value) {
        arguments[argumentIndex++] = value;
        names[nameIndex++] = _n(name);
      });
    }

    return reflect(_invokeConstructor(
        _reflectee, _reflectedType, _n(constructorName), arguments, names));
  }

  List<InstanceMirror> get metadata {
    // Get the metadata objects, convert them into InstanceMirrors using
    // reflect() and then make them into a Dart list.
    return new UnmodifiableListView(_metadata(_reflectee).map(reflect));
  }

  bool operator ==(other) {
    return this.runtimeType == other.runtimeType &&
        this._reflectee == other._reflectee &&
        this._reflectedType == other._reflectedType &&
        this._isGenericDeclaration == other._isGenericDeclaration;
  }

  int get hashCode => simpleName.hashCode;

  bool isSubtypeOf(TypeMirror other) {
    if (other == currentMirrorSystem().dynamicType) return true;
    if (other == currentMirrorSystem().voidType) return false;
    return _subtypeTest(_reflectedType, other._reflectedType);
  }

  bool isAssignableTo(TypeMirror other) {
    if (other == currentMirrorSystem().dynamicType) return true;
    if (other == currentMirrorSystem().voidType) return false;
    return _subtypeTest(_reflectedType, other._reflectedType) ||
        _subtypeTest(other._reflectedType, _reflectedType);
  }

  bool isSubclassOf(ClassMirror other) {
    if (other is! ClassMirror) throw new ArgumentError(other);
    ClassMirror otherDeclaration = other.originalDeclaration;
    ClassMirror c = this;
    while (c != null) {
      c = c.originalDeclaration;
      if (c == otherDeclaration) return true;
      c = c.superclass;
    }
    return false;
  }

  static _libraryUri(reflectee) native "ClassMirror_libraryUri";

  static _supertype(reflectedType) native "ClassMirror_supertype";

  static _supertypeInstantiated(reflectedType)
      native "ClassMirror_supertype_instantiated";

  static _nativeInterfaces(reflectedType) native "ClassMirror_interfaces";

  static _nativeInterfacesInstantiated(reflectedType)
      native "ClassMirror_interfaces_instantiated";

  static _nativeMixin(reflectedType) native "ClassMirror_mixin";

  static _nativeMixinInstantiated(reflectedType, instantiator)
      native "ClassMirror_mixin_instantiated";

  _computeMembers(reflectee, instantiator) native "ClassMirror_members";

  _computeConstructors(reflectee, instantiator)
      native "ClassMirror_constructors";

  _invoke(reflectee, memberName, arguments, argumentNames)
      native 'ClassMirror_invoke';

  _invokeGetter(reflectee, getterName) native 'ClassMirror_invokeGetter';

  _invokeSetter(reflectee, setterName, value) native 'ClassMirror_invokeSetter';

  static _invokeConstructor(reflectee, type, constructorName, arguments,
      argumentNames) native 'ClassMirror_invokeConstructor';

  static _ClassMirror_type_variables(reflectee)
      native "ClassMirror_type_variables";

  static _computeTypeArguments(reflectee) native "ClassMirror_type_arguments";
}

class _LocalFunctionTypeMirror extends _LocalClassMirror
    implements FunctionTypeMirror {
  final _functionReflectee;
  _LocalFunctionTypeMirror(reflectee, this._functionReflectee, reflectedType)
      : super(reflectee, reflectedType, null, null, false, false, false, false,
            false);

  bool get _isAnonymousMixinApplication => false;

  // FunctionTypeMirrors have a simpleName generated from their signature.
  Symbol _simpleName = null;
  Symbol get simpleName {
    if (_simpleName == null) {
      _simpleName = _s(_makeSignatureString(returnType, parameters));
    }
    return _simpleName;
  }

  MethodMirror _callMethod;
  MethodMirror get callMethod {
    if (_callMethod == null) {
      _callMethod = _FunctionTypeMirror_call_method(_functionReflectee);
    }
    return _callMethod;
  }

  TypeMirror _returnType = null;
  TypeMirror get returnType {
    if (_returnType == null) {
      _returnType =
          reflectType(_FunctionTypeMirror_return_type(_functionReflectee));
    }
    return _returnType;
  }

  List<ParameterMirror> _parameters = null;
  List<ParameterMirror> get parameters {
    if (_parameters == null) {
      _parameters = _FunctionTypeMirror_parameters(_functionReflectee);
      _parameters = new UnmodifiableListView(_parameters);
    }
    return _parameters;
  }

  bool get isOriginalDeclaration => true;
  get originalDeclaration => this;
  get typeVariables => _emptyList;
  get typeArguments => _emptyList;
  get metadata => _emptyList;
  get location => null;

  String toString() => "FunctionTypeMirror on '${_n(simpleName)}'";

  MethodMirror _FunctionTypeMirror_call_method(functionReflectee)
      native "FunctionTypeMirror_call_method";

  static Type _FunctionTypeMirror_return_type(functionReflectee)
      native "FunctionTypeMirror_return_type";

  List<ParameterMirror> _FunctionTypeMirror_parameters(functionReflectee)
      native "FunctionTypeMirror_parameters";
}

abstract class _LocalDeclarationMirror extends _LocalMirror
    implements DeclarationMirror {
  final _reflectee;
  Symbol _simpleName;

  _LocalDeclarationMirror(this._reflectee, this._simpleName);

  Symbol get simpleName => _simpleName;

  Symbol _qualifiedName = null;
  Symbol get qualifiedName {
    if (_qualifiedName == null) {
      _qualifiedName = _computeQualifiedName(owner, simpleName);
    }
    return _qualifiedName;
  }

  bool get isPrivate => _n(simpleName).startsWith('_');

  SourceLocation get location {
    return _location(_reflectee);
  }

  List<InstanceMirror> get metadata {
    // Get the metadata objects, convert them into InstanceMirrors using
    // reflect() and then make them into a Dart list.
    return new UnmodifiableListView(_metadata(_reflectee).map(reflect));
  }

  bool operator ==(other) {
    return this.runtimeType == other.runtimeType &&
        this._reflectee == other._reflectee;
  }

  int get hashCode => simpleName.hashCode;
}

class _LocalTypeVariableMirror extends _LocalDeclarationMirror
    implements TypeVariableMirror {
  _LocalTypeVariableMirror(reflectee, String simpleName, this._owner)
      : super(reflectee, _s(simpleName));

  DeclarationMirror _owner;
  DeclarationMirror get owner {
    if (_owner == null) {
      _owner = _TypeVariableMirror_owner(_reflectee).originalDeclaration;
    }
    return _owner;
  }

  bool get isStatic => false;
  bool get isTopLevel => false;

  TypeMirror _upperBound = null;
  TypeMirror get upperBound {
    if (_upperBound == null) {
      _upperBound = reflectType(_TypeVariableMirror_upper_bound(_reflectee));
    }
    return _upperBound;
  }

  bool get hasReflectedType => false;
  Type get reflectedType {
    throw new UnsupportedError('Type variables have no reflected type');
  }

  Type get _reflectedType => _reflectee;

  List<TypeVariableMirror> get typeVariables => _emptyList;
  List<TypeMirror> get typeArguments => _emptyList;

  bool get isOriginalDeclaration => true;
  TypeMirror get originalDeclaration => this;

  String toString() => "TypeVariableMirror on '${_n(simpleName)}'";

  operator ==(other) {
    return other is TypeVariableMirror &&
        simpleName == other.simpleName &&
        owner == other.owner;
  }

  int get hashCode => simpleName.hashCode;

  bool isSubtypeOf(TypeMirror other) {
    if (other == currentMirrorSystem().dynamicType) return true;
    if (other == currentMirrorSystem().voidType) return false;
    return _subtypeTest(_reflectedType, other._reflectedType);
  }

  bool isAssignableTo(TypeMirror other) {
    if (other == currentMirrorSystem().dynamicType) return true;
    if (other == currentMirrorSystem().voidType) return false;
    return _subtypeTest(_reflectedType, other._reflectedType) ||
        _subtypeTest(other._reflectedType, _reflectedType);
  }

  static DeclarationMirror _TypeVariableMirror_owner(reflectee)
      native "TypeVariableMirror_owner";

  static Type _TypeVariableMirror_upper_bound(reflectee)
      native "TypeVariableMirror_upper_bound";
}

class _LocalTypedefMirror extends _LocalDeclarationMirror
    implements TypedefMirror {
  final Type _reflectedType;
  final bool _isGeneric;
  final bool _isGenericDeclaration;

  _LocalTypedefMirror(reflectee, this._reflectedType, String simpleName,
      this._isGeneric, this._isGenericDeclaration, this._owner)
      : super(reflectee, _s(simpleName));

  bool get isTopLevel => true;

  DeclarationMirror _owner;
  DeclarationMirror get owner {
    if (_owner == null) {
      var uri = _LocalClassMirror._libraryUri(_reflectee);
      _owner = currentMirrorSystem().libraries[Uri.parse(uri)];
    }
    return _owner;
  }

  TypeMirror _referent = null;
  TypeMirror get referent {
    if (_referent == null) {
      _referent = _nativeReferent(_reflectedType);
      _referent._instantiator = _reflectedType;
    }
    return _referent;
  }

  bool get hasReflectedType => !_isGenericDeclaration;
  Type get reflectedType {
    if (!hasReflectedType) {
      throw new UnsupportedError(
          "Declarations of generics have no reflected type");
    }
    return _reflectedType;
  }

  bool get isOriginalDeclaration => !_isGeneric || _isGenericDeclaration;

  TypedefMirror get originalDeclaration {
    if (isOriginalDeclaration) {
      return this;
    } else {
      return _nativeDeclaration(_reflectedType);
    }
  }

  List<TypeVariableMirror> _typeVariables = null;
  List<TypeVariableMirror> get typeVariables {
    if (_typeVariables == null) {
      _typeVariables = new List<TypeVariableMirror>();
      List params = _LocalClassMirror._ClassMirror_type_variables(_reflectee);
      TypedefMirror owner = originalDeclaration;
      var mirror;
      for (var i = 0; i < params.length; i += 2) {
        mirror = new _LocalTypeVariableMirror(params[i + 1], params[i], owner);
        _typeVariables.add(mirror);
      }
    }
    return _typeVariables;
  }

  List<TypeMirror> _typeArguments = null;
  List<TypeMirror> get typeArguments {
    if (_typeArguments == null) {
      if (_isGenericDeclaration) {
        _typeArguments = _emptyList;
      } else {
        _typeArguments = new UnmodifiableListView(
            _LocalClassMirror._computeTypeArguments(_reflectedType));
      }
    }
    return _typeArguments;
  }

  String toString() => "TypedefMirror on '${_n(simpleName)}'";

  bool isSubtypeOf(TypeMirror other) {
    if (other == currentMirrorSystem().dynamicType) return true;
    if (other == currentMirrorSystem().voidType) return false;
    return _subtypeTest(_reflectedType, other._reflectedType);
  }

  bool isAssignableTo(TypeMirror other) {
    if (other == currentMirrorSystem().dynamicType) return true;
    if (other == currentMirrorSystem().voidType) return false;
    return _subtypeTest(_reflectedType, other._reflectedType) ||
        _subtypeTest(other._reflectedType, _reflectedType);
  }

  static _nativeReferent(reflectedType) native "TypedefMirror_referent";

  static _nativeDeclaration(reflectedType) native "TypedefMirror_declaration";
}

Symbol _asSetter(Symbol getter, LibraryMirror library) {
  var unwrapped = MirrorSystem.getName(getter);
  return MirrorSystem.getSymbol('${unwrapped}=', library);
}

class _LocalLibraryMirror extends _LocalObjectMirror implements LibraryMirror {
  final Symbol simpleName;
  final Uri uri;

  _LocalLibraryMirror(reflectee, String simpleName, String url)
      : this.simpleName = _s(simpleName),
        this.uri = Uri.parse(url),
        super(reflectee);

  // The simple name and the qualified name are the same for a library.
  Symbol get qualifiedName => simpleName;

  DeclarationMirror get owner => null;

  bool get isPrivate => false;
  bool get isTopLevel => false;

  Type get _instantiator => null;

  Map<Symbol, DeclarationMirror> _declarations;
  Map<Symbol, DeclarationMirror> get declarations {
    if (_declarations != null) return _declarations;

    var decls = new Map<Symbol, DeclarationMirror>();
    var members = _computeMembers(_reflectee);
    for (var member in members) {
      decls[member.simpleName] = member;
    }

    return _declarations =
        new UnmodifiableMapView<Symbol, DeclarationMirror>(decls);
  }

  SourceLocation get location {
    return _location(_reflectee);
  }

  List<InstanceMirror> get metadata {
    // Get the metadata objects, convert them into InstanceMirrors using
    // reflect() and then make them into a Dart list.
    return new UnmodifiableListView(_metadata(_reflectee).map(reflect));
  }

  bool operator ==(other) {
    return this.runtimeType == other.runtimeType &&
        this._reflectee == other._reflectee;
  }

  int get hashCode => simpleName.hashCode;

  String toString() => "LibraryMirror on '${_n(simpleName)}'";

  var _cachedLibraryDependencies;
  get libraryDependencies {
    if (_cachedLibraryDependencies == null) {
      _cachedLibraryDependencies = _libraryDependencies(_reflectee);
    }
    return _cachedLibraryDependencies;
  }

  _libraryDependencies(reflectee) native 'LibraryMirror_libraryDependencies';

  _invoke(reflectee, memberName, arguments, argumentNames)
      native 'LibraryMirror_invoke';

  _invokeGetter(reflectee, getterName) native 'LibraryMirror_invokeGetter';

  _invokeSetter(reflectee, setterName, value)
      native 'LibraryMirror_invokeSetter';

  _computeMembers(reflectee) native "LibraryMirror_members";
}

class _LocalLibraryDependencyMirror extends _LocalMirror
    implements LibraryDependencyMirror {
  final LibraryMirror sourceLibrary;
  var _targetMirrorOrPrefix;
  final List<CombinatorMirror> combinators;
  final Symbol prefix;
  final bool isImport;
  final bool isDeferred;
  final List<InstanceMirror> metadata;

  _LocalLibraryDependencyMirror(
      this.sourceLibrary,
      this._targetMirrorOrPrefix,
      this.combinators,
      prefixString,
      this.isImport,
      this.isDeferred,
      unwrappedMetadata)
      : prefix = _s(prefixString),
        metadata = new UnmodifiableListView(unwrappedMetadata.map(reflect));

  bool get isExport => !isImport;

  LibraryMirror get targetLibrary {
    if (_targetMirrorOrPrefix is _LocalLibraryMirror) {
      return _targetMirrorOrPrefix;
    }
    var mirrorOrNull = _tryUpgradePrefix(_targetMirrorOrPrefix);
    if (mirrorOrNull != null) {
      _targetMirrorOrPrefix = mirrorOrNull;
    }
    return mirrorOrNull;
  }

  Future<LibraryMirror> loadLibrary() {
    if (_targetMirrorOrPrefix is _LocalLibraryMirror) {
      return new Future.value(_targetMirrorOrPrefix);
    }
    var savedPrefix = _targetMirrorOrPrefix;
    return savedPrefix.loadLibrary().then((_) {
      return _tryUpgradePrefix(savedPrefix);
    });
  }

  static _tryUpgradePrefix(libraryPrefix) native "LibraryMirror_fromPrefix";
}

class _LocalCombinatorMirror extends _LocalMirror implements CombinatorMirror {
  final List<Symbol> identifiers;
  final bool isShow;

  _LocalCombinatorMirror(identifierString, this.isShow)
      : this.identifiers = [_s(identifierString)];

  bool get isHide => !isShow;
}

class _LocalMethodMirror extends _LocalDeclarationMirror
    implements MethodMirror {
  final Type _instantiator;
  final bool isStatic;
  final int _kindFlags;

  _LocalMethodMirror(reflectee, String simpleName, this._owner,
      this._instantiator, this.isStatic, this._kindFlags)
      : super(reflectee, _s(simpleName));

  static const kAbstract = 0;
  static const kGetter = 1;
  static const kSetter = 2;
  static const kConstructor = 3;
  static const kConstCtor = 4;
  static const kGenerativeCtor = 5;
  static const kRedirectingCtor = 6;
  static const kFactoryCtor = 7;
  static const kExternal = 8;

  // These offsets much be kept in sync with those in mirrors.h.
  bool get isAbstract => 0 != (_kindFlags & (1 << kAbstract));
  bool get isGetter => 0 != (_kindFlags & (1 << kGetter));
  bool get isSetter => 0 != (_kindFlags & (1 << kSetter));
  bool get isConstructor => 0 != (_kindFlags & (1 << kConstructor));
  bool get isConstConstructor => 0 != (_kindFlags & (1 << kConstCtor));
  bool get isGenerativeConstructor =>
      0 != (_kindFlags & (1 << kGenerativeCtor));
  bool get isRedirectingConstructor =>
      0 != (_kindFlags & (1 << kRedirectingCtor));
  bool get isFactoryConstructor => 0 != (_kindFlags & (1 << kFactoryCtor));
  bool get isExternal => 0 != (_kindFlags & (1 << kExternal));

  static const _operators = const [
    "%", "&", "*", "+", "-", "/", "<", "<<", //
    "<=", "==", ">", ">=", ">>", "[]", "[]=",
    "^", "|", "~", "unary-", "~/",
  ];
  bool get isOperator => _operators.contains(_n(simpleName));

  DeclarationMirror _owner;
  DeclarationMirror get owner {
    // For nested closures it is possible, that the mirror for the owner has not
    // been created yet.
    if (_owner == null) {
      _owner = _MethodMirror_owner(_reflectee, _instantiator);
    }
    return _owner;
  }

  bool get isPrivate =>
      _n(simpleName).startsWith('_') || _n(constructorName).startsWith('_');

  bool get isTopLevel => owner is LibraryMirror;
  bool get isSynthetic => false;

  TypeMirror _returnType = null;
  TypeMirror get returnType {
    if (_returnType == null) {
      if (isConstructor) {
        _returnType = owner;
      } else {
        _returnType =
            reflectType(_MethodMirror_return_type(_reflectee, _instantiator));
      }
    }
    return _returnType;
  }

  List<ParameterMirror> _parameters = null;
  List<ParameterMirror> get parameters {
    if (_parameters == null) {
      _parameters = _MethodMirror_parameters(_reflectee);
      _parameters = new UnmodifiableListView(_parameters);
    }
    return _parameters;
  }

  bool get isRegularMethod => !isGetter && !isSetter && !isConstructor;

  Symbol _constructorName = null;
  Symbol get constructorName {
    if (_constructorName == null) {
      if (!isConstructor) {
        _constructorName = _s('');
      } else {
        var parts = MirrorSystem.getName(simpleName).split('.');
        if (parts.length > 2) {
          throw new _InternalMirrorError(
              'Internal error in MethodMirror.constructorName: '
              'malformed name <$simpleName>');
        } else if (parts.length == 2) {
          LibraryMirror definingLibrary = owner.owner;
          _constructorName = MirrorSystem.getSymbol(parts[1], definingLibrary);
        } else {
          _constructorName = _s('');
        }
      }
    }
    return _constructorName;
  }

  String get source => _MethodMirror_source(_reflectee);

  void _patchConstructorName(ownerName) {
    var cn = _n(constructorName);
    if (cn == '') {
      _simpleName = _s(ownerName);
    } else {
      _simpleName = _s(ownerName + "." + cn);
    }
  }

  String toString() => "MethodMirror on '${MirrorSystem.getName(simpleName)}'";

  static dynamic _MethodMirror_owner(reflectee, instantiator)
      native "MethodMirror_owner";

  static dynamic _MethodMirror_return_type(reflectee, instantiator)
      native "MethodMirror_return_type";

  List<ParameterMirror> _MethodMirror_parameters(reflectee)
      native "MethodMirror_parameters";

  static String _MethodMirror_source(reflectee) native "MethodMirror_source";
}

class _LocalVariableMirror extends _LocalDeclarationMirror
    implements VariableMirror {
  final DeclarationMirror owner;
  final bool isStatic;
  final bool isFinal;
  final bool isConst;

  _LocalVariableMirror(reflectee, String simpleName, this.owner, this._type,
      this.isStatic, this.isFinal, this.isConst)
      : super(reflectee, _s(simpleName));

  bool get isTopLevel => owner is LibraryMirror;

  Type get _instantiator {
    return owner._instantiator;
  }

  TypeMirror _type;
  TypeMirror get type {
    if (_type == null) {
      _type = reflectType(_VariableMirror_type(_reflectee, _instantiator));
    }
    return _type;
  }

  String toString() =>
      "VariableMirror on '${MirrorSystem.getName(simpleName)}'";

  static _VariableMirror_type(reflectee, instantiator)
      native "VariableMirror_type";
}

class _LocalParameterMirror extends _LocalVariableMirror
    implements ParameterMirror {
  final int _position;
  final bool isOptional;
  final bool isNamed;
  final List _unmirroredMetadata;

  _LocalParameterMirror(
      reflectee,
      String simpleName,
      DeclarationMirror owner,
      this._position,
      this.isOptional,
      this.isNamed,
      bool isFinal,
      this._defaultValueReflectee,
      this._unmirroredMetadata)
      : super(
            reflectee,
            simpleName,
            owner,
            null, // We override the type.
            false, // isStatic does not apply.
            isFinal,
            false // Not const.
            );

  Object _defaultValueReflectee;
  InstanceMirror _defaultValue;
  InstanceMirror get defaultValue {
    if (!isOptional) {
      return null;
    }
    if (_defaultValue == null) {
      _defaultValue = reflect(_defaultValueReflectee);
    }
    return _defaultValue;
  }

  bool get hasDefaultValue => _defaultValueReflectee != null;

  SourceLocation get location {
    throw new UnsupportedError("ParameterMirror.location unimplemented");
  }

  List<InstanceMirror> get metadata {
    if (_unmirroredMetadata == null) return _emptyList;
    return new UnmodifiableListView(_unmirroredMetadata.map(reflect));
  }

  Type get _instantiator {
    return owner._instantiator;
  }

  TypeMirror _type = null;
  TypeMirror get type {
    if (_type == null) {
      _type = reflectType(
          _ParameterMirror_type(_reflectee, _position, _instantiator));
    }
    return _type;
  }

  String toString() => "ParameterMirror on '${_n(simpleName)}'";

  static Type _ParameterMirror_type(_reflectee, _position, instantiator)
      native "ParameterMirror_type";
}

class _SpecialTypeMirror extends _LocalMirror
    implements TypeMirror, DeclarationMirror {
  final Symbol simpleName;

  _SpecialTypeMirror(String name) : simpleName = _s(name);

  bool get isPrivate => false;
  bool get isTopLevel => true;

  DeclarationMirror get owner => null;

  SourceLocation get location => null;
  List<InstanceMirror> get metadata => _emptyList;

  bool get hasReflectedType => simpleName == #dynamic;
  Type get reflectedType {
    if (simpleName == #dynamic) return dynamic;
    throw new UnsupportedError("void has no reflected type");
  }

  List<TypeVariableMirror> get typeVariables => _emptyList;
  List<TypeMirror> get typeArguments => _emptyList;

  bool get isOriginalDeclaration => true;
  TypeMirror get originalDeclaration => this;

  Symbol get qualifiedName => simpleName;

  bool operator ==(other) {
    if (other is! _SpecialTypeMirror) {
      return false;
    }
    return this.simpleName == other.simpleName;
  }

  int get hashCode => simpleName.hashCode;

  String toString() => "TypeMirror on '${_n(simpleName)}'";

  bool isSubtypeOf(TypeMirror other) {
    return simpleName == #dynamic || other is _SpecialTypeMirror;
  }

  bool isAssignableTo(TypeMirror other) {
    return simpleName == #dynamic || other is _SpecialTypeMirror;
  }
}

class _Mirrors {
  static MirrorSystem _currentMirrorSystem = new _LocalMirrorSystem();
  static MirrorSystem currentMirrorSystem() {
    return _currentMirrorSystem;
  }

  // Creates a new local mirror for some Object.
  static InstanceMirror reflect(Object reflectee) {
    return reflectee is Function
        ? new _LocalClosureMirror(reflectee)
        : new _LocalInstanceMirror(reflectee);
  }

  static ClassMirror makeLocalClassMirror(Type key)
      native "Mirrors_makeLocalClassMirror";
  static TypeMirror makeLocalTypeMirror(Type key)
      native "Mirrors_makeLocalTypeMirror";
  static Type instantiateGenericType(Type key, typeArguments)
      native "Mirrors_instantiateGenericType";

  static Expando<ClassMirror> _declarationCache = new Expando("ClassMirror");
  static Expando<TypeMirror> _instantiationCache = new Expando("TypeMirror");

  static ClassMirror reflectClass(Type key) {
    var classMirror = _declarationCache[key];
    if (classMirror == null) {
      classMirror = makeLocalClassMirror(key);
      _declarationCache[key] = classMirror;
      if (!classMirror._isGeneric) {
        _instantiationCache[key] = classMirror;
      }
    }
    return classMirror;
  }

  static TypeMirror reflectType(Type key, [List<Type> typeArguments]) {
    if (typeArguments != null) {
      key = _instantiateType(key, typeArguments);
    }
    var typeMirror = _instantiationCache[key];
    if (typeMirror == null) {
      typeMirror = makeLocalTypeMirror(key);
      _instantiationCache[key] = typeMirror;
      if (typeMirror is ClassMirror && !typeMirror._isGeneric) {
        _declarationCache[key] = typeMirror;
      }
    }
    return typeMirror;
  }

  static Type _instantiateType(Type key, List<Type> typeArguments) {
    if (typeArguments.isEmpty) {
      throw new ArgumentError.value(typeArguments, 'typeArguments',
          'Type arguments list cannot be empty.');
    }
    return instantiateGenericType(key, typeArguments.toList(growable: false));
  }
}
