// 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.

library dart._js_mirrors;

import 'dart:_js_embedded_names'
    show
        JsGetName,
        ALL_CLASSES,
        LAZIES,
        LIBRARIES,
        STATICS,
        TYPE_INFORMATION,
        TYPEDEF_PREDICATE_PROPERTY_NAME,
        TYPEDEF_TYPE_PROPERTY_NAME;

import 'dart:collection' show UnmodifiableListView, UnmodifiableMapView;

import 'dart:mirrors';

import 'dart:_foreign_helper'
    show
        JS,
        JS_GET_FLAG,
        JS_GET_STATIC_STATE,
        JS_CURRENT_ISOLATE_CONTEXT,
        JS_EMBEDDED_GLOBAL,
        JS_GET_NAME;

import 'dart:_internal' as _symbol_dev;

import 'dart:_js_helper'
    show
        BoundClosure,
        CachedInvocation,
        Closure,
        JSInvocationMirror,
        JsCache,
        Primitives,
        ReflectionInfo,
        RuntimeError,
        TearOffClosure,
        TypeVariable,
        UnimplementedNoSuchMethodError,
        createRuntimeType,
        createUnmangledInvocationMirror,
        extractFunctionTypeObjectFrom,
        getMangledTypeName,
        getMetadata,
        getType,
        getRuntimeType,
        isDartFunctionType,
        runtimeTypeToString,
        setRuntimeTypeInfo,
        throwInvalidReflectionError,
        TypeImpl,
        deferredLoadHook;

import 'dart:_interceptors'
    show Interceptor, JSArray, JSExtendableArray, getInterceptor;

import 'dart:_js_names';

const String METHODS_WITH_OPTIONAL_ARGUMENTS = r'$methodsWithOptionalArguments';

bool hasReflectableProperty(var jsFunction) {
  return JS('bool', '# in #', JS_GET_NAME(JsGetName.REFLECTABLE), jsFunction);
}

/// No-op method that is called to inform the compiler that tree-shaking needs
/// to be disabled.
disableTreeShaking() => preserveNames();

/// No-op method that is called to inform the compiler that metadata must be
/// preserved at runtime.
preserveMetadata() {}

/// No-op method that is called to inform the compiler that the compiler must
/// preserve the URIs.
preserveUris() {}

/// No-op method that is called to inform the compiler that the compiler must
/// preserve the library names.
preserveLibraryNames() {}

String getName(Symbol symbol) {
  preserveNames();
  return n(symbol);
}

class JsMirrorSystem implements MirrorSystem {
  UnmodifiableMapView<Uri, LibraryMirror> _cachedLibraries;

  final IsolateMirror isolate = new JsIsolateMirror();

  JsTypeMirror get dynamicType => _dynamicType;
  JsTypeMirror get voidType => _voidType;

  static final JsTypeMirror _dynamicType =
      new JsTypeMirror(const Symbol('dynamic'));
  static final JsTypeMirror _voidType = new JsTypeMirror(const Symbol('void'));

  static Map<String, List<LibraryMirror>> _librariesByName;

  // Will be set to `true` when we have installed a hook on [deferredLoadHook]
  // to avoid installing it multiple times.
  static bool _hasInstalledDeferredLoadHook = false;

  static Map<String, List<LibraryMirror>> get librariesByName {
    if (_librariesByName == null) {
      _librariesByName = computeLibrariesByName();
      if (!_hasInstalledDeferredLoadHook) {
        _hasInstalledDeferredLoadHook = true;
        // After a deferred import has been loaded new libraries might have
        // been created, so in the hook we erase _librariesByName, so it will be
        // recomputed on the next access.
        deferredLoadHook = () => _librariesByName = null;
      }
    }
    return _librariesByName;
  }

  Map<Uri, LibraryMirror> get libraries {
    if (_cachedLibraries != null) return _cachedLibraries;
    Map<Uri, LibraryMirror> result = new Map();
    for (List<LibraryMirror> list in librariesByName.values) {
      for (LibraryMirror library in list) {
        result[library.uri] = library;
      }
    }
    return _cachedLibraries =
        new UnmodifiableMapView<Uri, LibraryMirror>(result);
  }

  LibraryMirror findLibrary(Symbol libraryName) {
    return librariesByName[n(libraryName)].single;
  }

  static Map<String, List<LibraryMirror>> computeLibrariesByName() {
    disableTreeShaking();
    var result = new Map<String, List<LibraryMirror>>();
    var jsLibraries = JS_EMBEDDED_GLOBAL('JSExtendableArray|Null', LIBRARIES);
    if (jsLibraries == null) return result;
    for (List data in jsLibraries) {
      String name = data[0];
      String uriString = data[1];
      Uri uri;
      // The Uri has been compiled out. Create a URI from the simple name.
      if (uriString != '') {
        uri = Uri.parse(uriString);
      } else {
        uri = new Uri(
            scheme: 'https',
            host: 'dartlang.org',
            path: 'dart2js-stripped-uri',
            queryParameters: {'lib': name});
      }
      List<String> classes = data[2];
      List<String> functions = data[3];
      var metadataFunction = data[4];
      var fields = data[5];
      bool isRoot = data[6];
      var globalObject = data[7];
      List metadata = (metadataFunction == null)
          ? const []
          : JS('List', '#()', metadataFunction);
      var libraries = result.putIfAbsent(name, () => <LibraryMirror>[]);
      libraries.add(new JsLibraryMirror(s(name), uri, classes, functions,
          metadata, fields, isRoot, globalObject));
    }
    return result;
  }
}

abstract class JsMirror implements Mirror {
  const JsMirror();

  String get _prettyName;

  String toString() => _prettyName;

  // TODO(ahe): Remove this method from the API.
  MirrorSystem get mirrors => currentJsMirrorSystem;

  _getField(JsMirror receiver) {
    throw new UnimplementedError();
  }

  void _setField(JsMirror receiver, Object arg) {
    throw new UnimplementedError();
  }

  _loadField(String name) {
    throw new UnimplementedError();
  }

  void _storeField(String name, Object arg) {
    throw new UnimplementedError();
  }
}

// This class is somewhat silly in the current implementation.
class JsIsolateMirror extends JsMirror implements IsolateMirror {
  final _isolateContext = JS_CURRENT_ISOLATE_CONTEXT();

  String get _prettyName => 'Isolate';

  String get debugName {
    String id = _isolateContext == null ? 'X' : _isolateContext.id.toString();
    // Using name similar to what the VM uses.
    return '${n(rootLibrary.simpleName)}-$id';
  }

  bool get isCurrent => JS_CURRENT_ISOLATE_CONTEXT() == _isolateContext;

  LibraryMirror get rootLibrary {
    return currentJsMirrorSystem.libraries.values
        .firstWhere((JsLibraryMirror library) => library._isRoot);
  }
}

abstract class JsDeclarationMirror extends JsMirror
    implements DeclarationMirror {
  final Symbol simpleName;

  const JsDeclarationMirror(this.simpleName);

  Symbol get qualifiedName => computeQualifiedName(owner, simpleName);

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

  bool get isTopLevel => owner != null && owner is LibraryMirror;

  // TODO(ahe): This should use qualifiedName.
  String toString() => "$_prettyName on '${n(simpleName)}'";

  List<JsMethodMirror> get _methods {
    throw new RuntimeError('Should not call _methods');
  }

  _invoke(List positionalArguments, Map<Symbol, dynamic> namedArguments) {
    throw new RuntimeError('Should not call _invoke');
  }

  // TODO(ahe): Implement this.
  SourceLocation get location => throw new UnimplementedError();
}

class JsTypeVariableMirror extends JsTypeMirror implements TypeVariableMirror {
  final DeclarationMirror owner;
  final TypeVariable _typeVariable;
  final int _metadataIndex;
  TypeMirror _cachedUpperBound;

  JsTypeVariableMirror(
      TypeVariable typeVariable, this.owner, this._metadataIndex)
      : this._typeVariable = typeVariable,
        super(s(typeVariable.name));

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

  int get hashCode {
    int code = 0x3FFFFFFF & (JsTypeVariableMirror).hashCode;
    code ^= 17 * simpleName.hashCode;
    code ^= 19 * owner.hashCode;
    return code;
  }

  String get _prettyName => 'TypeVariableMirror';

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

  TypeMirror get upperBound {
    if (_cachedUpperBound != null) return _cachedUpperBound;
    return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation(
        owner, getType(_typeVariable.bound));
  }

  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();

  _asRuntimeType() => _metadataIndex;
}

class JsTypeMirror extends JsDeclarationMirror implements TypeMirror {
  JsTypeMirror(Symbol simpleName) : super(simpleName);

  String get _prettyName => 'TypeMirror';

  DeclarationMirror get owner => null;

  // TODO(ahe): Doesn't match the specification, see http://dartbug.com/11569.
  bool get isTopLevel => true;

  // TODO(ahe): Implement these.
  List<InstanceMirror> get metadata => throw new UnimplementedError();

  bool get hasReflectedType => false;
  Type get reflectedType {
    throw new UnsupportedError('This type does not support reflectedType');
  }

  List<TypeVariableMirror> get typeVariables => const <TypeVariableMirror>[];
  List<TypeMirror> get typeArguments => const <TypeMirror>[];

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

  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();

  _asRuntimeType() {
    if (this == JsMirrorSystem._dynamicType) return null;
    if (this == JsMirrorSystem._voidType) return null;
    throw new RuntimeError('Should not call _asRuntimeType');
  }
}

class JsLibraryMirror extends JsDeclarationMirror
    with JsObjectMirror
    implements LibraryMirror {
  final Uri _uri;
  final List<String> _classes;
  final List<String> _functions;
  final List _metadata;
  final String _compactFieldSpecification;
  final bool _isRoot;
  final _globalObject;
  List<JsMethodMirror> _cachedFunctionMirrors;
  List<VariableMirror> _cachedFields;
  UnmodifiableMapView<Symbol, ClassMirror> _cachedClasses;
  UnmodifiableMapView<Symbol, MethodMirror> _cachedFunctions;
  UnmodifiableMapView<Symbol, MethodMirror> _cachedGetters;
  UnmodifiableMapView<Symbol, MethodMirror> _cachedSetters;
  UnmodifiableMapView<Symbol, VariableMirror> _cachedVariables;
  UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
  UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
  UnmodifiableListView<InstanceMirror> _cachedMetadata;

  JsLibraryMirror(
      Symbol simpleName,
      this._uri,
      this._classes,
      this._functions,
      this._metadata,
      this._compactFieldSpecification,
      this._isRoot,
      this._globalObject)
      : super(simpleName) {
    preserveLibraryNames();
  }

  String get _prettyName => 'LibraryMirror';

  Uri get uri {
    preserveUris();
    return _uri;
  }

  Symbol get qualifiedName => simpleName;

  List<JsMethodMirror> get _methods => _functionMirrors;

  Map<Symbol, ClassMirror> get __classes {
    if (_cachedClasses != null) return _cachedClasses;
    var result = new Map();
    for (String className in _classes) {
      var cls = reflectClassByMangledName(className);
      if (cls is ClassMirror) {
        cls = cls.originalDeclaration;
      }
      if (cls is JsClassMirror) {
        result[cls.simpleName] = cls;
        cls._owner = this;
      } else if (cls is JsTypedefMirror) {
        result[cls.simpleName] = cls;
      }
    }
    return _cachedClasses =
        new UnmodifiableMapView<Symbol, ClassMirror>(result);
  }

  InstanceMirror setField(Symbol fieldName, Object arg) {
    String name = n(fieldName);
    if (name.endsWith('=')) throw new ArgumentError('');
    var mirror = __functions[s('$name=')];
    if (mirror == null) mirror = __variables[fieldName];
    if (mirror == null) {
      throw new NoSuchStaticMethodError.method(
          null, setterSymbol(fieldName), [arg], null);
    }
    mirror._setField(this, arg);
    return reflect(arg);
  }

  InstanceMirror getField(Symbol fieldName) {
    JsMirror mirror = __members[fieldName];
    if (mirror == null) {
      throw new NoSuchStaticMethodError.method(null, fieldName, [], null);
    }
    if (mirror is! MethodMirror) return reflect(mirror._getField(this));
    JsMethodMirror methodMirror = mirror;
    if (methodMirror.isGetter) return reflect(mirror._getField(this));
    assert(methodMirror.isRegularMethod);
    var getter = JS('', "#['\$getter']", methodMirror._jsFunction);
    if (getter == null) throw new UnimplementedError();
    return reflect(JS('', '#()', getter));
  }

  InstanceMirror invoke(Symbol memberName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    if (namedArguments != null && !namedArguments.isEmpty) {
      throw new UnsupportedError('Named arguments are not implemented.');
    }
    JsDeclarationMirror mirror = __members[memberName];

    if (mirror is JsMethodMirror && !mirror.canInvokeReflectively()) {
      throwInvalidReflectionError(n(memberName));
    }
    if (mirror == null || mirror is JsMethodMirror && mirror.isSetter) {
      throw new NoSuchStaticMethodError.method(
          null, memberName, positionalArguments, namedArguments);
    }
    if (mirror is JsMethodMirror && !mirror.isGetter) {
      return reflect(mirror._invoke(positionalArguments, namedArguments));
    }
    return getField(memberName)
        .invoke(#call, positionalArguments, namedArguments);
  }

  delegate(Invocation invocation) {
    throw new UnimplementedError();
  }

  _loadField(String name) {
    // TODO(ahe): What about lazily initialized fields? See
    // [JsClassMirror.getField].

    // '$' (JS_GET_STATIC_STATE()) stores state which is read directly, so we
    // shouldn't use [_globalObject] here.
    assert(JS('bool', '# in #', name, JS_GET_STATIC_STATE()));
    return JS('', '#[#]', JS_GET_STATIC_STATE(), name);
  }

  void _storeField(String name, Object arg) {
    // '$' (JS_GET_STATIC_STATE()) stores state which is stored directly, so we
    // shouldn't use [_globalObject] here.
    assert(JS('bool', '# in #', name, JS_GET_STATIC_STATE()));
    JS('void', '#[#] = #', JS_GET_STATIC_STATE(), name, arg);
  }

  List<JsMethodMirror> get _functionMirrors {
    if (_cachedFunctionMirrors != null) return _cachedFunctionMirrors;
    var result = new List<JsMethodMirror>();
    for (int i = 0; i < _functions.length; i++) {
      String name = _functions[i];
      var jsFunction = JS('', '#[#]', _globalObject, name);
      String unmangledName = mangledGlobalNames[name];
      if (unmangledName == null ||
          JS('bool', "!!#['\$getterStub']", jsFunction)) {
        // If there is no unmangledName, [jsFunction] is either a synthetic
        // implementation detail, or something that is excluded
        // by @MirrorsUsed.
        // If it has a getterStub property it is a synthetic stub.
        // TODO(floitsch): Remove the getterStub hack.
        continue;
      }
      bool isConstructor = unmangledName.startsWith('new ');
      // Top-level functions are static, but constructors are not.
      bool isStatic = !isConstructor;
      if (isConstructor) {
        unmangledName = unmangledName.substring(4).replaceAll(r'$', '.');
      }
      JsMethodMirror mirror = new JsMethodMirror.fromUnmangledName(
          unmangledName, jsFunction, isStatic, isConstructor);
      result.add(mirror);
      mirror._owner = this;
    }
    return _cachedFunctionMirrors = result;
  }

  List<VariableMirror> get _fields {
    if (_cachedFields != null) return _cachedFields;
    var result = <VariableMirror>[];
    parseCompactFieldSpecification(
        this, _compactFieldSpecification, true, result);
    return _cachedFields = result;
  }

  Map<Symbol, MethodMirror> get __functions {
    if (_cachedFunctions != null) return _cachedFunctions;
    var result = new Map();
    for (JsMethodMirror mirror in _functionMirrors) {
      if (!mirror.isConstructor) result[mirror.simpleName] = mirror;
    }
    return _cachedFunctions =
        new UnmodifiableMapView<Symbol, MethodMirror>(result);
  }

  Map<Symbol, MethodMirror> get __getters {
    if (_cachedGetters != null) return _cachedGetters;
    var result = new Map();
    // TODO(ahe): Implement this.
    return _cachedGetters =
        new UnmodifiableMapView<Symbol, MethodMirror>(result);
  }

  Map<Symbol, MethodMirror> get __setters {
    if (_cachedSetters != null) return _cachedSetters;
    var result = new Map();
    // TODO(ahe): Implement this.
    return _cachedSetters =
        new UnmodifiableMapView<Symbol, MethodMirror>(result);
  }

  Map<Symbol, VariableMirror> get __variables {
    if (_cachedVariables != null) return _cachedVariables;
    var result = new Map();
    for (JsVariableMirror mirror in _fields) {
      result[mirror.simpleName] = mirror;
    }
    return _cachedVariables =
        new UnmodifiableMapView<Symbol, VariableMirror>(result);
  }

  Map<Symbol, Mirror> get __members {
    if (_cachedMembers != null) return _cachedMembers;
    Map<Symbol, Mirror> result = new Map.from(__classes);
    addToResult(Symbol key, Mirror value) {
      result[key] = value;
    }

    __functions.forEach(addToResult);
    __getters.forEach(addToResult);
    __setters.forEach(addToResult);
    __variables.forEach(addToResult);
    return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(result);
  }

  Map<Symbol, DeclarationMirror> get declarations {
    if (_cachedDeclarations != null) return _cachedDeclarations;
    var result = new Map<Symbol, DeclarationMirror>();
    addToResult(Symbol key, Mirror value) {
      result[key] = value;
    }

    __members.forEach(addToResult);
    return _cachedDeclarations =
        new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
  }

  List<InstanceMirror> get metadata {
    if (_cachedMetadata != null) return _cachedMetadata;
    preserveMetadata();
    return _cachedMetadata =
        new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect));
  }

  // TODO(ahe): Test this getter.
  DeclarationMirror get owner => null;

  List<LibraryDependencyMirror> get libraryDependencies =>
      throw new UnimplementedError();
}

String n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);

Symbol s(String name) {
  if (name == null) return null;
  return new _symbol_dev.Symbol.unvalidated(name);
}

Symbol setterSymbol(Symbol symbol) => s('${n(symbol)}=');

final JsMirrorSystem currentJsMirrorSystem = new JsMirrorSystem();

InstanceMirror reflect(Object reflectee) {
  // TODO(sra): This test should be a quick test for something like 'is
  // Function', but only for classes that implement `Function` via a `call`
  // method. The JS form of the test could be something like
  //
  //     if (reflectee instanceof P.Object && reflectee.$isFunction) ...
  //
  // We don't currently have a way get that generated. We should ensure type
  // analysis can express 'not Interceptor' and recognize a negative type test
  // against Interceptor can be optimized to the above test. For now we have to
  // accept the following is compiled to an interceptor-based type check.
  if (reflectee is Function) {
    return new JsClosureMirror(reflectee);
  } else {
    return new JsInstanceMirror(reflectee);
  }
}

TypeMirror reflectType(Type key, [List<Type> typeArguments]) {
  String mangledName = getMangledTypeName(key);
  if (typeArguments != null) {
    if (typeArguments.isEmpty || !typeArguments.every((_) => _ is TypeImpl)) {
      var message = typeArguments.isEmpty
          ? 'Type arguments list can not be empty.'
          : 'Type arguments list must contain only instances of Type.';
      throw new ArgumentError.value(typeArguments, 'typeArguments', message);
    }
    var mangledTypeArguments = typeArguments.map(getMangledTypeName);
    mangledName = "${mangledName}<${mangledTypeArguments.join(', ')}>";
  }
  return reflectClassByMangledName(mangledName);
}

TypeMirror reflectClassByMangledName(String mangledName) {
  String unmangledName = mangledGlobalNames[mangledName];
  if (mangledName == 'dynamic') return JsMirrorSystem._dynamicType;
  if (mangledName == 'void') return JsMirrorSystem._voidType;
  if (unmangledName == null) unmangledName = mangledName;
  return reflectClassByName(s(unmangledName), mangledName);
}

var classMirrors;

TypeMirror reflectClassByName(Symbol symbol, String mangledName) {
  if (classMirrors == null) classMirrors = JsCache.allocate();
  var mirror = JsCache.fetch(classMirrors, mangledName);
  if (mirror != null) return mirror;
  disableTreeShaking();
  int typeArgIndex = mangledName.indexOf('<');
  if (typeArgIndex != -1) {
    TypeMirror originalDeclaration =
        reflectClassByMangledName(mangledName.substring(0, typeArgIndex))
            .originalDeclaration;
    if (originalDeclaration is JsTypedefMirror) {
      throw new UnimplementedError();
    }
    mirror = new JsTypeBoundClassMirror(
        originalDeclaration,
        // Remove the angle brackets enclosing the type arguments.
        mangledName.substring(typeArgIndex + 1, mangledName.length - 1));
    JsCache.update(classMirrors, mangledName, mirror);
    return mirror;
  }
  var allClasses = JS_EMBEDDED_GLOBAL('', ALL_CLASSES);
  var constructor = JS('var', '#[#]', allClasses, mangledName);
  if (constructor == null) {
    // Probably an intercepted class.
    // TODO(ahe): How to handle intercepted classes?
    throw new UnsupportedError('Cannot find class for: ${n(symbol)}');
  }
  var descriptor = JS('', '#["@"]', constructor);
  var fields;
  var fieldsMetadata;
  if (descriptor == null) {
    // This is a native class, or an intercepted class.
    // TODO(ahe): Preserve descriptor for such classes.
  } else if (JS(
      'bool', '# in #', TYPEDEF_PREDICATE_PROPERTY_NAME, descriptor)) {
    // Typedefs are represented as normal classes with two special properties:
    //   TYPEDEF_PREDICATE_PROPERTY_NAME and TYPEDEF_TYPE_PROPERTY_NAME.
    // For example:
    //  MyTypedef: {
    //     "^": "Object;",
    //     $typedefType: 58,
    //     $$isTypedef: true
    //  }
    //  The typedefType is the index into the metadata table.
    int index = JS('int', '#[#]', descriptor, TYPEDEF_TYPE_PROPERTY_NAME);
    mirror = new JsTypedefMirror(symbol, mangledName, getType(index));
  } else {
    fields = JS('', '#[#]', descriptor,
        JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY));
    if (fields is List) {
      fieldsMetadata = fields.getRange(1, fields.length).toList();
      fields = fields[0];
    }
    if (fields is! String) {
      // TODO(ahe): This is CSP mode.  Find a way to determine the
      // fields of this class.
      fields = '';
    }
  }

  if (mirror == null) {
    var superclassName = fields.split(';')[0];
    var mixins = superclassName.split('+');
    if (mixins.length > 1 && mangledGlobalNames[mangledName] == null) {
      mirror = reflectMixinApplication(mixins, mangledName);
    } else {
      ClassMirror classMirror = new JsClassMirror(
          symbol, mangledName, constructor, fields, fieldsMetadata);
      List typeVariables =
          JS('JSExtendableArray|Null', '#.prototype["<>"]', constructor);
      if (typeVariables == null || typeVariables.length == 0) {
        mirror = classMirror;
      } else {
        String typeArguments = 'dynamic';
        for (int i = 1; i < typeVariables.length; i++) {
          typeArguments += ',dynamic';
        }
        mirror = new JsTypeBoundClassMirror(classMirror, typeArguments);
      }
    }
  }

  JsCache.update(classMirrors, mangledName, mirror);
  return mirror;
}

/// Splits input `typeArguments` string into a list of strings for each argument.
/// Takes into account nested generic types.
/// For example, `Map<int, String>, String` will become a list of two items:
/// `Map<int, String>` and `String`.
List<String> splitTypeArguments(String typeArguments) {
  if (typeArguments.indexOf('<') == -1) {
    return typeArguments.split(',');
  }
  var argumentList = new List<String>();
  int level = 0;
  String currentTypeArgument = '';

  for (int i = 0; i < typeArguments.length; i++) {
    var character = typeArguments[i];
    if (character == ' ') {
      continue;
    } else if (character == '<') {
      currentTypeArgument += character;
      level++;
    } else if (character == '>') {
      currentTypeArgument += character;
      level--;
    } else if (character == ',') {
      if (level > 0) {
        currentTypeArgument += character;
      } else {
        argumentList.add(currentTypeArgument);
        currentTypeArgument = '';
      }
    } else {
      currentTypeArgument += character;
    }
  }
  argumentList.add(currentTypeArgument);
  return argumentList;
}

Map<Symbol, MethodMirror> filterMethods(List<MethodMirror> methods) {
  var result = new Map();
  for (JsMethodMirror method in methods) {
    if (!method.isConstructor && !method.isGetter && !method.isSetter) {
      result[method.simpleName] = method;
    }
  }
  return result;
}

Map<Symbol, MethodMirror> filterConstructors(methods) {
  var result = new Map();
  for (JsMethodMirror method in methods) {
    if (method.isConstructor) {
      result[method.simpleName] = method;
    }
  }
  return result;
}

Map<Symbol, MethodMirror> filterGetters(
    List<MethodMirror> methods, Map<Symbol, VariableMirror> fields) {
  var result = new Map();
  for (JsMethodMirror method in methods) {
    if (method.isGetter) {
      // TODO(ahe): This is a hack to remove getters corresponding to a field.
      if (fields[method.simpleName] != null) continue;

      result[method.simpleName] = method;
    }
  }
  return result;
}

Map<Symbol, MethodMirror> filterSetters(
    List<MethodMirror> methods, Map<Symbol, VariableMirror> fields) {
  var result = new Map();
  for (JsMethodMirror method in methods) {
    if (method.isSetter) {
      // TODO(ahe): This is a hack to remove setters corresponding to a field.
      String name = n(method.simpleName);
      name = name.substring(0, name.length - 1); // Remove '='.
      if (fields[s(name)] != null) continue;

      result[method.simpleName] = method;
    }
  }
  return result;
}

Map<Symbol, Mirror> filterMembers(
    List<MethodMirror> methods, Map<Symbol, VariableMirror> variables) {
  Map<Symbol, Mirror> result = new Map.from(variables);
  for (JsMethodMirror method in methods) {
    if (method.isSetter) {
      String name = n(method.simpleName);
      name = name.substring(0, name.length - 1);
      // Filter-out setters corresponding to variables.
      if (result[s(name)] is VariableMirror) continue;
    }
    // Constructors aren't 'members'.
    if (method.isConstructor) continue;
    // Filter out synthetic tear-off stubs
    if (JS('bool', r'!!#.$getterStub', method._jsFunction)) continue;
    // Use putIfAbsent to filter-out getters corresponding to variables.
    result.putIfAbsent(method.simpleName, () => method);
  }
  return result;
}

int counter = 0;

ClassMirror reflectMixinApplication(mixinNames, String mangledName) {
  disableTreeShaking();
  var mixins = [];
  for (String mangledName in mixinNames) {
    mixins.add(reflectClassByMangledName(mangledName));
  }
  var it = mixins.iterator;
  it.moveNext();
  var superclass = it.current;
  while (it.moveNext()) {
    superclass = new JsMixinApplication(superclass, it.current, mangledName);
  }
  return superclass;
}

class JsMixinApplication extends JsTypeMirror
    with JsObjectMirror
    implements ClassMirror {
  final ClassMirror superclass;
  final ClassMirror mixin;
  Symbol _cachedSimpleName;
  Map<Symbol, MethodMirror> _cachedInstanceMembers;

  JsMixinApplication(
      ClassMirror superclass, ClassMirror mixin, String mangledName)
      : this.superclass = superclass,
        this.mixin = mixin,
        super(s(mangledName));

  String get _prettyName => 'ClassMirror';

  Symbol get simpleName {
    if (_cachedSimpleName != null) return _cachedSimpleName;
    String superName = n(superclass.qualifiedName);
    return _cachedSimpleName = (superName.contains(' with '))
        ? s('$superName, ${n(mixin.qualifiedName)}')
        : s('$superName with ${n(mixin.qualifiedName)}');
  }

  Symbol get qualifiedName => simpleName;

  // TODO(ahe): Remove this method, only here to silence warning.
  get _mixin => mixin;

  Map<Symbol, Mirror> get __members => _mixin.__members;

  Map<Symbol, MethodMirror> get __methods => _mixin.__methods;

  Map<Symbol, MethodMirror> get __getters => _mixin.__getters;

  Map<Symbol, MethodMirror> get __setters => _mixin.__setters;

  Map<Symbol, VariableMirror> get __variables => _mixin.__variables;

  Map<Symbol, DeclarationMirror> get declarations => mixin.declarations;

  Map<Symbol, MethodMirror> get instanceMembers {
    if (_cachedInstanceMembers == null) {
      var result = new Map<Symbol, MethodMirror>();
      if (superclass != null) {
        result.addAll(superclass.instanceMembers);
      }
      result.addAll(mixin.instanceMembers);
      _cachedInstanceMembers = result;
    }
    return _cachedInstanceMembers;
  }

  Map<Symbol, MethodMirror> get staticMembers => mixin.staticMembers;

  _asRuntimeType() => null;

  InstanceMirror invoke(Symbol memberName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    throw new NoSuchStaticMethodError.method(
        null, memberName, positionalArguments, namedArguments);
  }

  InstanceMirror getField(Symbol fieldName) {
    throw new NoSuchStaticMethodError.method(null, fieldName, null, null);
  }

  InstanceMirror setField(Symbol fieldName, Object arg) {
    throw new NoSuchStaticMethodError.method(
        null, setterSymbol(fieldName), [arg], null);
  }

  delegate(Invocation invocation) {
    throw new UnimplementedError();
  }

  List<ClassMirror> get superinterfaces => [mixin];

  Map<Symbol, MethodMirror> get __constructors => _mixin.__constructors;

  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    throw new UnsupportedError(
        "Can't instantiate mixin application '${n(qualifiedName)}'");
  }

  bool get isOriginalDeclaration => true;

  ClassMirror get originalDeclaration => this;

  // TODO(ahe): Implement this.
  List<TypeVariableMirror> get typeVariables {
    throw new UnimplementedError();
  }

  List<TypeMirror> get typeArguments => const <TypeMirror>[];

  bool get isAbstract => throw new UnimplementedError();

  bool get isEnum => throw new UnimplementedError();

  bool isSubclassOf(ClassMirror other) {
    superclass.isSubclassOf(other) || mixin.isSubclassOf(other);
  }

  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();

  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
}

abstract class JsObjectMirror implements ObjectMirror {}

class JsInstanceMirror extends JsObjectMirror implements InstanceMirror {
  final reflectee;

  JsInstanceMirror(this.reflectee);

  bool get hasReflectee => true;

  ClassMirror get type {
    // The spec guarantees that `null` is the singleton instance of the `Null`
    // class.
    if (reflectee == null) return reflectClass(Null);
    return reflectType(getRuntimeType(reflectee));
  }

  InstanceMirror invoke(Symbol memberName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    if (namedArguments == null) namedArguments = const {};
    // We can safely pass positionalArguments to _invoke as it will wrap it in
    // a JSArray if needed.
    return _invoke(memberName, JSInvocationMirror.METHOD, positionalArguments,
        namedArguments);
  }

  InstanceMirror _invokeMethodWithNamedArguments(String reflectiveName,
      List positionalArguments, Map<Symbol, dynamic> namedArguments) {
    assert(namedArguments.isNotEmpty);
    var interceptor = getInterceptor(reflectee);

    var jsFunction = JS('', '#[#]', interceptor, reflectiveName);
    if (jsFunction == null) {
      // TODO(ahe): Invoke noSuchMethod.
      throw new UnimplementedNoSuchMethodError(
          'Invoking noSuchMethod with named arguments not implemented');
    }
    ReflectionInfo info = new ReflectionInfo(jsFunction);
    if (jsFunction == null) {
      // TODO(ahe): Invoke noSuchMethod.
      throw new UnimplementedNoSuchMethodError(
          'Invoking noSuchMethod with named arguments not implemented');
    }

    positionalArguments = new List.from(positionalArguments);
    // Check the number of positional arguments is valid.
    if (info.requiredParameterCount != positionalArguments.length) {
      // TODO(ahe): Invoke noSuchMethod.
      throw new UnimplementedNoSuchMethodError(
          'Invoking noSuchMethod with named arguments not implemented');
    }
    var defaultArguments = new Map();
    for (int i = 0; i < info.optionalParameterCount; i++) {
      var parameterName = info.parameterName(i + info.requiredParameterCount);
      var defaultValue =
          getMetadata(info.defaultValue(i + info.requiredParameterCount));
      defaultArguments[parameterName] = defaultValue;
    }
    namedArguments.forEach((Symbol symbol, value) {
      String parameter = n(symbol);
      if (defaultArguments.containsKey(parameter)) {
        defaultArguments[parameter] = value;
      } else {
        // Extraneous named argument.
        // TODO(ahe): Invoke noSuchMethod.
        throw new UnimplementedNoSuchMethodError(
            'Invoking noSuchMethod with named arguments not implemented');
      }
    });
    positionalArguments.addAll(defaultArguments.values);
    // TODO(ahe): Handle intercepted methods.
    return reflect(
        JS('', '#.apply(#, #)', jsFunction, reflectee, positionalArguments));
  }

  /// Grabs hold of the class-specific invocation cache for the reflectee.
  /// All reflectees with the same class share the same cache. The cache
  /// maps reflective names to cached invocation objects with enough decoded
  /// reflective information to know how to to invoke a specific member.
  get _classInvocationCache {
    String cacheName = Primitives.mirrorInvokeCacheName;
    var cacheHolder = (reflectee == null) ? getInterceptor(null) : reflectee;
    var cache = JS('', r'#.constructor[#]', cacheHolder, cacheName);
    if (cache == null) {
      cache = JsCache.allocate();
      JS('void', r'#.constructor[#] = #', cacheHolder, cacheName, cache);
    }
    return cache;
  }

  String _computeReflectiveName(Symbol symbolName, int type,
      List positionalArguments, Map<Symbol, dynamic> namedArguments) {
    String name = n(symbolName);
    switch (type) {
      case JSInvocationMirror.GETTER:
        return name;
      case JSInvocationMirror.SETTER:
        return '$name=';
      case JSInvocationMirror.METHOD:
        if (namedArguments.isNotEmpty) return '$name*';
        int nbArgs = positionalArguments.length as int;
        return '$name:$nbArgs';
    }
    throw new RuntimeError('Could not compute reflective name for $name');
  }

  /**
   * Returns a `CachedInvocation` or `CachedNoSuchMethodInvocation` for the
   * given member.
   *
   * Caches the result.
   */
  _getCachedInvocation(Symbol name, int type, String reflectiveName,
      List positionalArguments, Map<Symbol, dynamic> namedArguments) {
    var cache = _classInvocationCache;
    var cacheEntry = JsCache.fetch(cache, reflectiveName);
    var result;
    if (cacheEntry == null) {
      disableTreeShaking();
      String mangledName = reflectiveNames[reflectiveName];
      List<String> argumentNames = const [];

      // TODO(ahe): We don't need to create an invocation mirror here. The
      // logic from JSInvocationMirror.getCachedInvocation could easily be
      // inlined here.
      Invocation invocation = createUnmangledInvocationMirror(
          name, mangledName, type, positionalArguments, argumentNames);

      cacheEntry =
          JSInvocationMirror.getCachedInvocation(invocation, reflectee);
      JsCache.update(cache, reflectiveName, cacheEntry);
    }
    return cacheEntry;
  }

  bool _isReflectable(CachedInvocation cachedInvocation) {
    // TODO(floitsch): tear-off closure does not guarantee that the
    // function is reflectable.
    var method = cachedInvocation.jsFunction;
    return hasReflectableProperty(method) || reflectee is TearOffClosure;
  }

  /// Invoke the member specified through name and type on the reflectee.
  /// As a side-effect, this populates the class-specific invocation cache
  /// for the reflectee.
  InstanceMirror _invoke(Symbol name, int type, List positionalArguments,
      Map<Symbol, dynamic> namedArguments) {
    String reflectiveName =
        _computeReflectiveName(name, type, positionalArguments, namedArguments);

    if (namedArguments.isNotEmpty) {
      // TODO(floitsch): first, make sure it's not a getter.
      return _invokeMethodWithNamedArguments(
          reflectiveName, positionalArguments, namedArguments);
    }
    var cacheEntry = _getCachedInvocation(
        name, type, reflectiveName, positionalArguments, namedArguments);

    if (cacheEntry.isNoSuchMethod || !_isReflectable(cacheEntry)) {
      // Could be that we want to invoke a getter, or get a method.
      if (type == JSInvocationMirror.METHOD && _instanceFieldExists(name)) {
        return getField(name)
            .invoke(#call, positionalArguments, namedArguments);
      }

      if (type == JSInvocationMirror.SETTER) {
        // For setters we report the setter name "field=".
        name = s('${n(name)}=');
      }

      if (!cacheEntry.isNoSuchMethod) {
        // Not reflectable.
        throwInvalidReflectionError(reflectiveName);
      }

      String mangledName = reflectiveNames[reflectiveName];
      // TODO(ahe): Get the argument names.
      List<String> argumentNames = [];
      Invocation invocation = createUnmangledInvocationMirror(
          name, mangledName, type, positionalArguments, argumentNames);
      return reflect(cacheEntry.invokeOn(reflectee, invocation));
    } else {
      return reflect(cacheEntry.invokeOn(reflectee, positionalArguments));
    }
  }

  InstanceMirror setField(Symbol fieldName, Object arg) {
    _invoke(fieldName, JSInvocationMirror.SETTER, [arg], const {});
    return reflect(arg);
  }

  // JS helpers for getField optimizations.
  static bool isUndefined(x) => JS('bool', 'typeof # == "undefined"', x);
  static bool isMissingCache(x) => JS('bool', 'typeof # == "number"', x);
  static bool isMissingProbe(Symbol symbol) =>
      JS('bool', 'typeof #.\$p == "undefined"', symbol);
  static bool isEvalAllowed() => !JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY');

  /// The getter cache is lazily allocated after a couple
  /// of invocations of [InstanceMirror.getField]. The delay is
  /// used to avoid too aggressive caching and dynamic function
  /// generation for rarely used mirrors. The cache is specific to
  /// this [InstanceMirror] and maps reflective names to functions
  /// that will invoke the corresponding getter on the reflectee.
  /// The reflectee is passed to the function as the first argument
  /// to avoid the overhead of fetching it from this mirror repeatedly.
  /// The cache is lazily initialized to a JS object so we can
  /// benefit from "map transitions" in the underlying JavaScript
  /// engine to speed up cache probing.
  var _getterCache = 4;

  bool _instanceFieldExists(Symbol name) {
    int getterType = JSInvocationMirror.GETTER;
    String getterName =
        _computeReflectiveName(name, getterType, const [], const {});
    var getterCacheEntry =
        _getCachedInvocation(name, getterType, getterName, const [], const {});
    return !getterCacheEntry.isNoSuchMethod && !getterCacheEntry.isGetterStub;
  }

  InstanceMirror getField(Symbol fieldName) {
    FASTPATH:
    {
      var cache = _getterCache;
      if (isMissingCache(cache) || isMissingProbe(fieldName)) break FASTPATH;
      // If the [fieldName] has an associated probe function, we can use
      // it to read from the getter cache specific to this [InstanceMirror].
      var getter = JS('', '#.\$p(#)', fieldName, cache);
      if (isUndefined(getter)) break FASTPATH;
      // Call the getter passing the reflectee as the first argument.
      var value = JS('', '#(#)', getter, reflectee);
      // The getter has an associate cache of the last [InstanceMirror]
      // returned to avoid repeated invocations of [reflect]. To validate
      // the cache, we check that the value returned by the getter is the
      // same value as last time.
      if (JS('bool', '# === #.v', value, getter)) {
        return JS('InstanceMirror', '#.m', getter);
      } else {
        var result = reflect(value);
        JS('void', '#.v = #', getter, value);
        JS('void', '#.m = #', getter, result);
        return result;
      }
    }
    return _getFieldSlow(fieldName);
  }

  InstanceMirror _getFieldSlow(Symbol fieldName) {
    // First do the slow-case getter invocation. As a side-effect of this,
    // the invocation cache is filled in so we can query it afterwards.
    var result =
        _invoke(fieldName, JSInvocationMirror.GETTER, const [], const {});
    String name = n(fieldName);
    var cacheEntry = JsCache.fetch(_classInvocationCache, name);
    if (cacheEntry.isNoSuchMethod) {
      return result;
    }

    // Make sure we have a getter cache in this [InstanceMirror].
    var cache = _getterCache;
    if (isMissingCache(cache)) {
      if ((_getterCache = --cache) != 0) return result;
      cache = _getterCache = JS('=Object', 'Object.create(null)');
    }

    // Make sure that symbol [fieldName] has a cache probing function ($p).
    bool useEval = isEvalAllowed();
    if (isMissingProbe(fieldName)) {
      var probe = _newProbeFn(name, useEval);
      JS('void', '#.\$p = #', fieldName, probe);
    }

    // Create a new getter function and install it in the cache.
    var mangledName = cacheEntry.mangledName;
    var getter = (cacheEntry.isIntercepted)
        ? _newInterceptedGetterFn(mangledName, useEval)
        : _newGetterFn(mangledName, useEval);
    JS('void', '#[#] = #', cache, name, getter);

    // Initialize the last value (v) and last mirror (m) on the
    // newly generated getter to be a sentinel value that is hard
    // to get hold of through user code.
    JS('void', '#.v = #.m = #', getter, getter, cache);

    // Return the result of the slow-path getter invocation.
    return result;
  }

  _newProbeFn(String id, bool useEval) {
    if (useEval) {
      String body = 'return c.$id;';
      return JS('', 'new Function("c", #)', body);
    } else {
      return JS('', '(function(n){return(function(c){return c[n]})})(#)', id);
    }
  }

  _newGetterFn(String name, bool useEval) {
    if (!useEval) return _newGetterNoEvalFn(name);
    // We use a comment that associates the generated function with the
    // class of the reflectee. This makes it more likely that the underlying
    // JavaScript engine will only share the generated code for accessors on the
    // same class (through caching of eval'ed code). This makes the
    // generated call to the getter - e.g. o.get$foo() - much more likely
    // to be monomorphic and inlineable.
    String className = JS('String', '#.constructor.name', reflectee);
    String body = '/* $className */ return o.$name();';
    return JS('', 'new Function("o", #)', body);
  }

  _newGetterNoEvalFn(n) =>
      JS('', '(function(n){return(function(o){return o[n]()})})(#)', n);

  _newInterceptedGetterFn(String name, bool useEval) {
    var object = reflectee;
    // It is possible that the interceptor for a given object is the object
    // itself, so it is important not to share the code that captures the
    // interceptor between multiple different instances of [InstanceMirror].
    var interceptor = getInterceptor(object);
    if (!useEval) return _newInterceptGetterNoEvalFn(name, interceptor);
    String className = JS('String', '#.constructor.name', interceptor);
    String functionName = '$className\$$name';
    String body = '  function $functionName(o){return i.$name(o)}'
        '  return $functionName;';
    return JS('', '(new Function("i", #))(#)', body, interceptor);
  }

  _newInterceptGetterNoEvalFn(n, i) =>
      JS('', '(function(n,i){return(function(o){return i[n](o)})})(#,#)', n, i);

  delegate(Invocation invocation) {
    return JSInvocationMirror.invokeFromMirror(invocation, reflectee);
  }

  operator ==(other) {
    return other is JsInstanceMirror && 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;
  }

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

  // TODO(ahe): Remove this method from the API.
  MirrorSystem get mirrors => currentJsMirrorSystem;
}

/**
 * ClassMirror for generic classes where the type parameters are bound.
 *
 * [typeArguments] will return a list of the type arguments, in contrast
 * to JsClassMirror that returns an empty list since it represents original
 * declarations and classes that are not generic.
 */
class JsTypeBoundClassMirror extends JsDeclarationMirror
    implements ClassMirror {
  final JsClassMirror _class;

  /**
   * When instantiated this field will hold a string representing the list of
   * type arguments for the class, i.e. what is inside the outermost angle
   * brackets. Then, when get typeArguments is called the first time, the string
   * is parsed into the actual list of TypeMirrors, and stored in
   * [_cachedTypeArguments]. Due to type substitution of, for instance,
   * superclasses the mangled name of the class and hence this string is needed
   * after [_cachedTypeArguments] has been computed.
   *
   * If an integer is encountered as a type argument, it represents the type
   * variable at the corresponding entry in [emitter.globalMetadata].
   */
  String _typeArguments;

  UnmodifiableListView<TypeMirror> _cachedTypeArguments;
  UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
  UnmodifiableMapView<Symbol, DeclarationMirror> _cachedMembers;
  UnmodifiableMapView<Symbol, MethodMirror> _cachedConstructors;
  Map<Symbol, VariableMirror> _cachedVariables;
  Map<Symbol, MethodMirror> _cachedGetters;
  Map<Symbol, MethodMirror> _cachedSetters;
  Map<Symbol, MethodMirror> _cachedMethodsMap;
  List<JsMethodMirror> _cachedMethods;
  ClassMirror _superclass;
  List<ClassMirror> _cachedSuperinterfaces;
  Map<Symbol, MethodMirror> _cachedInstanceMembers;
  Map<Symbol, MethodMirror> _cachedStaticMembers;

  JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments)
      : _class = originalDeclaration,
        super(originalDeclaration.simpleName);

  String get _prettyName => 'ClassMirror';

  String toString() {
    String result = '$_prettyName on ${n(simpleName)}';
    if (typeArguments != null) {
      result = "$result<${typeArguments.join(', ')}>";
    }
    return result;
  }

  String get _mangledName {
    for (TypeMirror typeArgument in typeArguments) {
      if (typeArgument != JsMirrorSystem._dynamicType) {
        return '${_class._mangledName}<$_typeArguments>';
      }
    }
    // When all type arguments are dynamic, the canonical representation is to
    // drop them.
    return _class._mangledName;
  }

  List<TypeVariableMirror> get typeVariables => _class.typeVariables;

  List<TypeMirror> get typeArguments {
    if (_cachedTypeArguments != null) return _cachedTypeArguments;
    List result = new List();

    addTypeArgument(String typeArgument) {
      int parsedIndex = int.parse(typeArgument, onError: (_) => -1);
      if (parsedIndex == -1) {
        result.add(reflectClassByMangledName(typeArgument.trim()));
      } else {
        TypeVariable typeVariable = getMetadata(parsedIndex);
        TypeMirror owner = reflectClass(typeVariable.owner);
        TypeVariableMirror typeMirror =
            new JsTypeVariableMirror(typeVariable, owner, parsedIndex);
        result.add(typeMirror);
      }
    }

    splitTypeArguments(_typeArguments).forEach(addTypeArgument);
    return _cachedTypeArguments = new UnmodifiableListView(result);
  }

  List<JsMethodMirror> get _methods {
    if (_cachedMethods != null) return _cachedMethods;
    return _cachedMethods = _class._getMethodsWithOwner(this);
  }

  Map<Symbol, MethodMirror> get __methods {
    if (_cachedMethodsMap != null) return _cachedMethodsMap;
    return _cachedMethodsMap =
        new UnmodifiableMapView<Symbol, MethodMirror>(filterMethods(_methods));
  }

  Map<Symbol, MethodMirror> get __constructors {
    if (_cachedConstructors != null) return _cachedConstructors;
    return _cachedConstructors = new UnmodifiableMapView<Symbol, MethodMirror>(
        filterConstructors(_methods));
  }

  Map<Symbol, MethodMirror> get __getters {
    if (_cachedGetters != null) return _cachedGetters;
    return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>(
        filterGetters(_methods, __variables));
  }

  Map<Symbol, MethodMirror> get __setters {
    if (_cachedSetters != null) return _cachedSetters;
    return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>(
        filterSetters(_methods, __variables));
  }

  Map<Symbol, VariableMirror> get __variables {
    if (_cachedVariables != null) return _cachedVariables;
    var result = new Map();
    for (JsVariableMirror mirror in _class._getFieldsWithOwner(this)) {
      result[mirror.simpleName] = mirror;
    }
    return _cachedVariables =
        new UnmodifiableMapView<Symbol, VariableMirror>(result);
  }

  Map<Symbol, DeclarationMirror> get __members {
    if (_cachedMembers != null) return _cachedMembers;
    return _cachedMembers = new UnmodifiableMapView<Symbol, DeclarationMirror>(
        filterMembers(_methods, __variables));
  }

  Map<Symbol, DeclarationMirror> get declarations {
    if (_cachedDeclarations != null) return _cachedDeclarations;
    Map<Symbol, DeclarationMirror> result =
        new Map<Symbol, DeclarationMirror>();
    result.addAll(__members);
    result.addAll(__constructors);
    typeVariables.forEach((tv) => result[tv.simpleName] = tv);
    return _cachedDeclarations =
        new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
  }

  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 JsSyntheticAccessor(
              this, getterName, true, true, false, decl);
          if (!decl.isFinal) {
            var setterName = setterSymbol(decl.simpleName);
            result[setterName] = new JsSyntheticAccessor(
                this, setterName, false, true, false, decl);
          }
        }
      });
      _cachedStaticMembers = result;
    }
    return _cachedStaticMembers;
  }

  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 JsSyntheticAccessor(
              this, getterName, true, false, false, decl);
          if (!decl.isFinal) {
            var setterName = setterSymbol(decl.simpleName);
            result[setterName] = new JsSyntheticAccessor(
                this, setterName, false, false, false, decl);
          }
        }
      });
      _cachedInstanceMembers = result;
    }
    return _cachedInstanceMembers;
  }

  InstanceMirror setField(Symbol fieldName, Object arg) {
    return _class.setField(fieldName, arg);
  }

  InstanceMirror getField(Symbol fieldName) => _class.getField(fieldName);

  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    var instance = _class._getInvokedInstance(
        constructorName, positionalArguments, namedArguments);
    return reflect(setRuntimeTypeInfo(
        instance, typeArguments.map((t) => t._asRuntimeType()).toList()));
  }

  _asRuntimeType() {
    return [_class._jsConstructor]
        .addAll(typeArguments.map((t) => t._asRuntimeType()));
  }

  JsLibraryMirror get owner => _class.owner;

  List<InstanceMirror> get metadata => _class.metadata;

  ClassMirror get superclass {
    if (_superclass != null) return _superclass;

    var typeInformationContainer = JS_EMBEDDED_GLOBAL('', TYPE_INFORMATION);
    List<int> typeInformation =
        JS('List|Null', '#[#]', typeInformationContainer, _class._mangledName);
    assert(typeInformation != null);
    var type = getType(typeInformation[0]);
    return _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
  }

  InstanceMirror invoke(Symbol memberName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    return _class.invoke(memberName, positionalArguments, namedArguments);
  }

  delegate(Invocation invocation) {
    throw new UnimplementedError();
  }

  bool get isOriginalDeclaration => false;

  ClassMirror get originalDeclaration => _class;

  List<ClassMirror> get superinterfaces {
    if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
    return _cachedSuperinterfaces = _class._getSuperinterfacesWithOwner(this);
  }

  bool get isPrivate => _class.isPrivate;

  bool get isTopLevel => _class.isTopLevel;

  bool get isAbstract => _class.isAbstract;

  bool get isEnum => _class.isEnum;

  bool isSubclassOf(ClassMirror other) => _class.isSubclassOf(other);

  SourceLocation get location => _class.location;

  MirrorSystem get mirrors => _class.mirrors;

  Symbol get qualifiedName => _class.qualifiedName;

  bool get hasReflectedType => true;

  Type get reflectedType => createRuntimeType(_mangledName);

  Symbol get simpleName => _class.simpleName;

  // TODO(ahe): Implement this.
  ClassMirror get mixin => throw new UnimplementedError();

  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();

  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
}

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

  /// The field or type that introduces the synthetic accessor.
  final _target;

  JsSyntheticAccessor(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 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 const [];
    return new UnmodifiableListView(
        [new JsSyntheticSetterParameter(this, this._target)]);
  }

  List<InstanceMirror> get metadata => const [];
  String get source => null;
  SourceLocation get location => throw new UnimplementedError();
}

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

  JsSyntheticSetterParameter(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;
  List<InstanceMirror> get metadata => const [];
  SourceLocation get location => throw new UnimplementedError();
}

class JsClassMirror extends JsTypeMirror
    with JsObjectMirror
    implements ClassMirror {
  final String _mangledName;
  final _jsConstructor;
  final String _fieldsDescriptor;
  final List _fieldsMetadata;
  final _jsConstructorCache = JsCache.allocate();
  List _metadata;
  ClassMirror _superclass;
  List<JsMethodMirror> _cachedMethods;
  List<VariableMirror> _cachedFields;
  UnmodifiableMapView<Symbol, MethodMirror> _cachedConstructors;
  UnmodifiableMapView<Symbol, MethodMirror> _cachedMethodsMap;
  UnmodifiableMapView<Symbol, MethodMirror> _cachedGetters;
  UnmodifiableMapView<Symbol, MethodMirror> _cachedSetters;
  UnmodifiableMapView<Symbol, VariableMirror> _cachedVariables;
  UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
  UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
  UnmodifiableListView<InstanceMirror> _cachedMetadata;
  UnmodifiableListView<ClassMirror> _cachedSuperinterfaces;
  UnmodifiableListView<TypeVariableMirror> _cachedTypeVariables;
  Map<Symbol, MethodMirror> _cachedInstanceMembers;
  Map<Symbol, MethodMirror> _cachedStaticMembers;

  // Set as side-effect of accessing JsLibraryMirror.classes.
  JsLibraryMirror _owner;

  JsClassMirror(Symbol simpleName, this._mangledName, this._jsConstructor,
      this._fieldsDescriptor, this._fieldsMetadata)
      : super(simpleName);

  String get _prettyName => 'ClassMirror';

  Map<Symbol, MethodMirror> get __constructors {
    if (_cachedConstructors != null) return _cachedConstructors;
    return _cachedConstructors = new UnmodifiableMapView<Symbol, MethodMirror>(
        filterConstructors(_methods));
  }

  _asRuntimeType() {
    if (typeVariables.isEmpty) return _jsConstructor;
    var type = [_jsConstructor];
    for (int i = 0; i < typeVariables.length; i++) {
      type.add(JsMirrorSystem._dynamicType._asRuntimeType);
    }
    return type;
  }

  List<JsMethodMirror> _getMethodsWithOwner(DeclarationMirror methodOwner) {
    var prototype = JS('', '#.prototype', _jsConstructor);
    // The prototype might not have been processed yet, so do that now.
    JS('', '#[#]()', prototype,
        JS_GET_NAME(JsGetName.DEFERRED_ACTION_PROPERTY));
    List<String> keys = extractKeys(prototype);
    var result = <JsMethodMirror>[];
    for (String key in keys) {
      if (isReflectiveDataInPrototype(key)) continue;
      String simpleName = mangledNames[key];
      // [simpleName] can be null if [key] represents an implementation
      // detail, for example, a bailout method, or runtime type support.
      // It might also be null if the user has limited what is reified for
      // reflection with metadata.
      if (simpleName == null) continue;
      var function = JS('', '#[#]', prototype, key);
      if (!isOrdinaryReflectableMethod(function)) continue;
      if (isAliasedSuperMethod(function, key)) continue;
      var mirror = new JsMethodMirror.fromUnmangledName(
          simpleName, function, false, false);
      result.add(mirror);
      mirror._owner = methodOwner;
    }

    var statics = JS_EMBEDDED_GLOBAL('', STATICS);
    keys = extractKeys(JS('', '#[#]', statics, _mangledName));
    for (String mangledName in keys) {
      if (isReflectiveDataInPrototype(mangledName)) continue;
      String unmangledName = mangledName;
      var jsFunction = JS('', '#[#]', owner._globalObject, mangledName);

      bool isConstructor = false;
      if (hasReflectableProperty(jsFunction)) {
        String reflectionName =
            JS('String|Null', r'#.$reflectionName', jsFunction);
        if (reflectionName == null) continue;
        isConstructor = reflectionName.startsWith('new ');
        if (isConstructor) {
          reflectionName = reflectionName.substring(4).replaceAll(r'$', '.');
        }
        unmangledName = reflectionName;
      } else {
        continue;
      }
      bool isStatic = !isConstructor; // Constructors are not static.
      JsMethodMirror mirror = new JsMethodMirror.fromUnmangledName(
          unmangledName, jsFunction, isStatic, isConstructor);
      result.add(mirror);
      mirror._owner = methodOwner;
    }

    return result;
  }

  List<JsMethodMirror> get _methods {
    if (_cachedMethods != null) return _cachedMethods;
    return _cachedMethods = _getMethodsWithOwner(this);
  }

  List<VariableMirror> _getFieldsWithOwner(DeclarationMirror fieldOwner) {
    var result = <VariableMirror>[];

    var instanceFieldSpecfication = _fieldsDescriptor.split(';')[1];
    if (_fieldsMetadata != null) {
      instanceFieldSpecfication = [instanceFieldSpecfication]
        ..addAll(_fieldsMetadata);
    }
    parseCompactFieldSpecification(
        fieldOwner, instanceFieldSpecfication, false, result);

    var statics = JS_EMBEDDED_GLOBAL('', STATICS);
    var staticDescriptor = JS('', '#[#]', statics, _mangledName);
    if (staticDescriptor != null) {
      parseCompactFieldSpecification(
          fieldOwner,
          JS('', '#[#]', staticDescriptor,
              JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY)),
          true,
          result);
    }
    return result;
  }

  List<VariableMirror> get _fields {
    if (_cachedFields != null) return _cachedFields;
    return _cachedFields = _getFieldsWithOwner(this);
  }

  Map<Symbol, MethodMirror> get __methods {
    if (_cachedMethodsMap != null) return _cachedMethodsMap;
    return _cachedMethodsMap =
        new UnmodifiableMapView<Symbol, MethodMirror>(filterMethods(_methods));
  }

  Map<Symbol, MethodMirror> get __getters {
    if (_cachedGetters != null) return _cachedGetters;
    return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>(
        filterGetters(_methods, __variables));
  }

  Map<Symbol, MethodMirror> get __setters {
    if (_cachedSetters != null) return _cachedSetters;
    return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>(
        filterSetters(_methods, __variables));
  }

  Map<Symbol, VariableMirror> get __variables {
    if (_cachedVariables != null) return _cachedVariables;
    var result = new Map();
    for (JsVariableMirror mirror in _fields) {
      result[mirror.simpleName] = mirror;
    }
    return _cachedVariables =
        new UnmodifiableMapView<Symbol, VariableMirror>(result);
  }

  Map<Symbol, Mirror> get __members {
    if (_cachedMembers != null) return _cachedMembers;
    return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(
        filterMembers(_methods, __variables));
  }

  Map<Symbol, DeclarationMirror> get declarations {
    if (_cachedDeclarations != null) return _cachedDeclarations;
    var result = new Map<Symbol, DeclarationMirror>();
    addToResult(Symbol key, Mirror value) {
      result[key] = value;
    }

    __members.forEach(addToResult);
    __constructors.forEach(addToResult);
    typeVariables.forEach((tv) => result[tv.simpleName] = tv);
    return _cachedDeclarations =
        new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
  }

  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 JsSyntheticAccessor(
              this, getterName, true, true, false, decl);
          if (!decl.isFinal) {
            var setterName = setterSymbol(decl.simpleName);
            result[setterName] = new JsSyntheticAccessor(
                this, setterName, false, true, false, decl);
          }
        }
      });
      _cachedStaticMembers = result;
    }
    return _cachedStaticMembers;
  }

  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 JsSyntheticAccessor(
              this, getterName, true, false, false, decl);
          if (!decl.isFinal) {
            var setterName = setterSymbol(decl.simpleName);
            result[setterName] = new JsSyntheticAccessor(
                this, setterName, false, false, false, decl);
          }
        }
      });
      _cachedInstanceMembers = result;
    }
    return _cachedInstanceMembers;
  }

  InstanceMirror setField(Symbol fieldName, Object arg) {
    JsVariableMirror mirror = __variables[fieldName];
    if (mirror != null && mirror.isStatic && !mirror.isFinal) {
      // '$' (JS_GET_STATIC_STATE()) stores state which is stored directly, so
      // we shouldn't use [JsLibraryMirror._globalObject] here.
      String jsName = mirror._jsName;
      if (!JS('bool', '# in #', jsName, JS_GET_STATIC_STATE())) {
        throw new RuntimeError('Cannot find "$jsName" in current isolate.');
      }
      JS('void', '#[#] = #', JS_GET_STATIC_STATE(), jsName, arg);
      return reflect(arg);
    }
    Symbol setterName = setterSymbol(fieldName);
    if (mirror == null) {
      JsMethodMirror setter = __setters[setterName];
      if (setter != null) {
        setter._invoke([arg], const {});
        return reflect(arg);
      }
    }
    throw new NoSuchStaticMethodError.method(null, setterName, [arg], null);
  }

  bool _staticFieldExists(Symbol fieldName) {
    JsVariableMirror mirror = __variables[fieldName];
    if (mirror != null) return mirror.isStatic;
    JsMethodMirror getter = __getters[fieldName];
    return getter != null && getter.isStatic;
  }

  InstanceMirror getField(Symbol fieldName) {
    JsVariableMirror mirror = __variables[fieldName];
    if (mirror != null && mirror.isStatic) {
      String jsName = mirror._jsName;
      // '$' (JS_GET_STATIC_STATE()) stores state which is read directly, so
      // we shouldn't use [JsLibraryMirror._globalObject] here.
      if (!JS('bool', '# in #', jsName, JS_GET_STATIC_STATE())) {
        throw new RuntimeError('Cannot find "$jsName" in current isolate.');
      }
      var lazies = JS_EMBEDDED_GLOBAL('', LAZIES);
      if (JS('bool', '# in #', jsName, lazies)) {
        String getterName = JS('String', '#[#]', lazies, jsName);
        return reflect(JS('', '#[#]()', JS_GET_STATIC_STATE(), getterName));
      } else {
        return reflect(JS('', '#[#]', JS_GET_STATIC_STATE(), jsName));
      }
    }
    JsMethodMirror getter = __getters[fieldName];
    if (getter != null && getter.isStatic) {
      return reflect(getter._invoke(const [], const {}));
    }
    // If the fieldName designates a static function we have to return
    // its closure.
    JsMethodMirror method = __methods[fieldName];
    if (method != null && method.isStatic) {
      // We invoke the same getter that Dart code would execute. During
      // initialization we have stored that getter on the function (so that
      // we can find it more easily here).
      var getter = JS('', "#['\$getter']", method._jsFunction);
      if (getter == null) throw new UnimplementedError();
      return reflect(JS('', '#()', getter));
    }
    throw new NoSuchStaticMethodError.method(null, fieldName, null, null);
  }

  _getInvokedInstance(Symbol constructorName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    if (namedArguments != null && !namedArguments.isEmpty) {
      throw new UnsupportedError('Named arguments are not implemented.');
    }
    JsMethodMirror mirror =
        JsCache.fetch(_jsConstructorCache, n(constructorName));
    if (mirror == null) {
      mirror = __constructors.values
          .firstWhere((m) => m.constructorName == constructorName, orElse: () {
        throw new NoSuchStaticMethodError.method(
            null, constructorName, positionalArguments, namedArguments);
      });
      JsCache.update(_jsConstructorCache, n(constructorName), mirror);
    }
    return mirror._invoke(positionalArguments, namedArguments);
  }

  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    return reflect(_getInvokedInstance(
        constructorName, positionalArguments, namedArguments));
  }

  JsLibraryMirror get owner {
    if (_owner == null) {
      for (var list in JsMirrorSystem.librariesByName.values) {
        for (JsLibraryMirror library in list) {
          // This will set _owner field on all classes as a side
          // effect.  This gives us a fast path to reflect on a
          // class without parsing reflection data.
          library.__classes;
        }
      }
      if (_owner == null) {
        throw new StateError('Class "${n(simpleName)}" has no owner');
      }
    }
    return _owner;
  }

  List<InstanceMirror> get metadata {
    if (_cachedMetadata != null) return _cachedMetadata;
    if (_metadata == null) {
      _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor));
    }
    return _cachedMetadata =
        new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect));
  }

  ClassMirror get superclass {
    if (_superclass == null) {
      var typeInformationContainer = JS_EMBEDDED_GLOBAL('', TYPE_INFORMATION);
      List<int> typeInformation =
          JS('List|Null', '#[#]', typeInformationContainer, _mangledName);
      if (typeInformation != null) {
        var type = getType(typeInformation[0]);
        _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
      } else {
        var superclassName = _fieldsDescriptor.split(';')[0].split(':')[0];
        // TODO(zarah): Remove special handing of mixins.
        var mixins = superclassName.split('+');
        if (mixins.length > 1) {
          if (mixins.length != 2) {
            throw new RuntimeError('Strange mixin: $_fieldsDescriptor');
          }
          _superclass = reflectClassByMangledName(mixins[0]);
        } else {
          // Use _superclass == this to represent class with no superclass
          // (Object).
          _superclass = (superclassName == '')
              ? this
              : reflectClassByMangledName(superclassName);
        }
      }
    }
    return _superclass == this ? null : _superclass;
  }

  InstanceMirror invoke(Symbol memberName, List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    // Mirror API gotcha: Calling [invoke] on a ClassMirror means invoke a
    // static method.

    if (namedArguments != null && !namedArguments.isEmpty) {
      throw new UnsupportedError('Named arguments are not implemented.');
    }
    JsMethodMirror mirror = __methods[memberName];

    if (mirror == null && _staticFieldExists(memberName)) {
      return getField(memberName)
          .invoke(#call, positionalArguments, namedArguments);
    }
    if (mirror == null || !mirror.isStatic) {
      throw new NoSuchStaticMethodError.method(
          null, memberName, positionalArguments, namedArguments);
    }
    if (!mirror.canInvokeReflectively()) {
      throwInvalidReflectionError(n(memberName));
    }
    return reflect(mirror._invoke(positionalArguments, namedArguments));
  }

  delegate(Invocation invocation) {
    throw new UnimplementedError();
  }

  bool get isOriginalDeclaration => true;

  ClassMirror get originalDeclaration => this;

  List<ClassMirror> _getSuperinterfacesWithOwner(DeclarationMirror owner) {
    var typeInformationContainer = JS_EMBEDDED_GLOBAL('', TYPE_INFORMATION);
    List<int> typeInformation =
        JS('List|Null', '#[#]', typeInformationContainer, _mangledName);
    List<ClassMirror> result = const <ClassMirror>[];
    if (typeInformation != null) {
      ClassMirror lookupType(int i) {
        var type = getType(i);
        return typeMirrorFromRuntimeTypeRepresentation(owner, type);
      }

      //We skip the first since it is the supertype.
      result = typeInformation.skip(1).map(lookupType).toList();
    }

    return new UnmodifiableListView<ClassMirror>(result);
  }

  List<ClassMirror> get superinterfaces {
    if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
    return _cachedSuperinterfaces = _getSuperinterfacesWithOwner(this);
  }

  List<TypeVariableMirror> get typeVariables {
    if (_cachedTypeVariables != null) return _cachedTypeVariables;
    List result = new List();
    List typeVariables =
        JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor);
    if (typeVariables == null) return result;
    for (int i = 0; i < typeVariables.length; i++) {
      TypeVariable typeVariable = getMetadata(typeVariables[i]);
      result
          .add(new JsTypeVariableMirror(typeVariable, this, typeVariables[i]));
    }
    return _cachedTypeVariables = new UnmodifiableListView(result);
  }

  List<TypeMirror> get typeArguments => const <TypeMirror>[];

  bool get hasReflectedType => typeVariables.length == 0;

  Type get reflectedType {
    if (!hasReflectedType) {
      throw new UnsupportedError(
          'Declarations of generics have no reflected type');
    }
    return createRuntimeType(_mangledName);
  }

  // TODO(ahe): Implement this.
  ClassMirror get mixin => throw new UnimplementedError();

  bool get isAbstract => throw new UnimplementedError();

  bool get isEnum => throw new UnimplementedError();

  bool isSubclassOf(ClassMirror other) {
    if (other is! ClassMirror) {
      throw new ArgumentError(other);
    }
    if (other is JsFunctionTypeMirror) {
      return false;
    }
    if (other is JsClassMirror &&
        JS('bool', '# == #', other._jsConstructor, _jsConstructor)) {
      return true;
    } else if (superclass == null) {
      return false;
    } else {
      return superclass.isSubclassOf(other);
    }
  }
}

class JsVariableMirror extends JsDeclarationMirror implements VariableMirror {
  // TODO(ahe): The values in these fields are virtually untested.
  final String _jsName;
  final bool isFinal;
  final bool isStatic;
  final _metadataFunction;
  final DeclarationMirror _owner;
  final int _type;
  List _metadata;

  JsVariableMirror(Symbol simpleName, this._jsName, this._type, this.isFinal,
      this.isStatic, this._metadataFunction, this._owner)
      : super(simpleName);

  factory JsVariableMirror.from(String descriptor, metadataFunction,
      JsDeclarationMirror owner, bool isStatic) {
    List<String> fieldInformation = descriptor.split('-');
    if (fieldInformation.length == 1) {
      // The field is not available for reflection.
      // TODO(ahe): Should return an unreflectable field.
      return null;
    }

    String field = fieldInformation[0];
    int length = field.length;
    var code = fieldCode(field.codeUnitAt(length - 1));
    bool isFinal = false;
    if (code == 0) return null; // Inherited field.
    bool hasGetter = (code & 3) != 0;
    bool hasSetter = (code >> 2) != 0;
    isFinal = !hasSetter;
    length--;
    String jsName;
    String accessorName = jsName = field.substring(0, length);
    int divider = field.indexOf(':');
    if (divider > 0) {
      accessorName = accessorName.substring(0, divider);
      jsName = field.substring(divider + 1);
    }
    var unmangledName;
    if (isStatic) {
      unmangledName = mangledGlobalNames[accessorName];
    } else {
      String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX);
      unmangledName = mangledNames['$getterPrefix$accessorName'];
    }
    if (unmangledName == null) unmangledName = accessorName;
    if (!hasSetter) {
      // TODO(ahe): This is a hack to handle checked setters in checked mode.
      var setterName = s('$unmangledName=');
      for (JsMethodMirror method in owner._methods) {
        if (method.simpleName == setterName) {
          isFinal = false;
          break;
        }
      }
    }
    int type = int.parse(fieldInformation[1], onError: (_) => null);
    return new JsVariableMirror(s(unmangledName), jsName, type, isFinal,
        isStatic, metadataFunction, owner);
  }

  String get _prettyName => 'VariableMirror';

  TypeMirror get type {
    return typeMirrorFromRuntimeTypeRepresentation(owner, getType(_type));
  }

  DeclarationMirror get owner => _owner;

  List<InstanceMirror> get metadata {
    preserveMetadata();
    if (_metadata == null) {
      _metadata = (_metadataFunction == null)
          ? const []
          : JS('', '#()', _metadataFunction);
    }
    return _metadata.map(reflect).toList();
  }

  static int fieldCode(int code) {
    if (code >= 60 && code <= 64) return code - 59;
    if (code >= 123 && code <= 126) return code - 117;
    if (code >= 37 && code <= 43) return code - 27;
    return 0;
  }

  _getField(JsMirror receiver) => receiver._loadField(_jsName);

  void _setField(JsMirror receiver, Object arg) {
    if (isFinal) {
      // TODO(floitsch): when the field is non-static we don't want to have
      // a mirror as receiver.
      if (isStatic) {
        throw new NoSuchStaticMethodError.method(
            null, setterSymbol(simpleName), [arg], null);
      }
      throw new NoSuchMethodError(this, setterSymbol(simpleName), [arg], null);
    }
    receiver._storeField(_jsName, arg);
  }

  // TODO(ahe): Implement this method.
  bool get isConst => throw new UnimplementedError();
}

class JsClosureMirror extends JsInstanceMirror implements ClosureMirror {
  JsClosureMirror(reflectee) : super(reflectee);

  MethodMirror get function {
    String cacheName = Primitives.mirrorFunctionCacheName;
    JsMethodMirror cachedFunction;
    // TODO(ahe): Restore caching.
    //= JS('JsMethodMirror|Null', r'#.constructor[#]', reflectee, cacheName);
    if (cachedFunction != null) return cachedFunction;
    disableTreeShaking();
    // TODO(ahe): What about optional parameters (named or not).
    String callPrefix = '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$';

    String callName = JS(
        'String|Null',
        r'''
          (function(reflectee, callPrefix) {
            var properties = Object.keys(reflectee.constructor.prototype);
            var callPrefixLength = callPrefix.length;
            for (var i = 0; i < properties.length; i++) {
              var property = properties[i];
              if (callPrefix == property.substring(0, callPrefixLength) &&
                  property[callPrefixLength] >= "0" &&
                  property[callPrefixLength] <= "9") {
                return property;
              }
            }
            return null;
          })(#, #)''',
        reflectee,
        callPrefix);

    if (callName == null) {
      throw new RuntimeError('Cannot find callName on "$reflectee"');
    }
    // TODO(floitsch): What about optional parameters?
    int parameterCount = int.parse(callName.split(r'$')[1]);
    if (reflectee is BoundClosure) {
      var target = BoundClosure.targetOf(reflectee);
      var self = BoundClosure.selfOf(reflectee);
      var name = mangledNames[BoundClosure.nameOf(reflectee)];
      if (name == null) {
        throwInvalidReflectionError(name);
      }
      cachedFunction =
          new JsMethodMirror.fromUnmangledName(name, target, false, false);
    } else {
      bool isStatic = true; // TODO(ahe): Compute isStatic correctly.
      var jsFunction = JS('', '#[#]', reflectee, callName);
      var dummyOptionalParameterCount = 0;
      cachedFunction = new JsMethodMirror(
          s(callName),
          jsFunction,
          parameterCount,
          dummyOptionalParameterCount,
          false,
          false,
          isStatic,
          false,
          false);
    }
    JS('void', r'#.constructor[#] = #', reflectee, cacheName, cachedFunction);
    return cachedFunction;
  }

  InstanceMirror apply(List positionalArguments,
      [Map<Symbol, dynamic> namedArguments]) {
    return reflect(
        Function.apply(reflectee, positionalArguments, namedArguments));
  }

  TypeMirror get type {
    // Classes that implement [call] do not subclass [Closure], but only
    // implement [Function], so are rejected by this test.
    if (reflectee is Closure) {
      var functionRti = extractFunctionTypeObjectFrom(reflectee);
      if (functionRti != null) {
        return new JsFunctionTypeMirror(functionRti, null);
      }
    }
    // Use the JsInstanceMirror method to return the JsClassMirror.
    // TODO(sra): Should there be a TypeMirror that is both a ClassMirror and
    // FunctionTypeMirror?
    return super.type;
  }

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

  // TODO(ahe): Implement this method.
  String get source => throw new UnimplementedError();
}

class JsMethodMirror extends JsDeclarationMirror implements MethodMirror {
  final _jsFunction;
  final int _requiredParameterCount;
  final int _optionalParameterCount;
  final bool isGetter;
  final bool isSetter;
  final bool isStatic;
  final bool isConstructor;
  final bool isOperator;
  DeclarationMirror _owner;
  List _metadata;
  TypeMirror _returnType;
  UnmodifiableListView<ParameterMirror> _parameters;

  JsMethodMirror(
      Symbol simpleName,
      this._jsFunction,
      this._requiredParameterCount,
      this._optionalParameterCount,
      this.isGetter,
      this.isSetter,
      this.isStatic,
      this.isConstructor,
      this.isOperator)
      : super(simpleName);

  factory JsMethodMirror.fromUnmangledName(
      String name, jsFunction, bool isStatic, bool isConstructor) {
    List<String> info = name.split(':');
    name = info[0];
    bool isOperator = isOperatorName(name);
    bool isSetter = !isOperator && name.endsWith('=');
    int requiredParameterCount = 0;
    int optionalParameterCount = 0;
    bool isGetter = false;
    if (info.length == 1) {
      if (isSetter) {
        requiredParameterCount = 1;
      } else {
        isGetter = true;
        requiredParameterCount = 0;
      }
    } else {
      ReflectionInfo reflectionInfo = new ReflectionInfo(jsFunction);
      requiredParameterCount = reflectionInfo.requiredParameterCount;
      optionalParameterCount = reflectionInfo.optionalParameterCount;
      assert(int.parse(info[1]) ==
          requiredParameterCount + optionalParameterCount);
    }
    return new JsMethodMirror(
        s(name),
        jsFunction,
        requiredParameterCount,
        optionalParameterCount,
        isGetter,
        isSetter,
        isStatic,
        isConstructor,
        isOperator);
  }

  String get _prettyName => 'MethodMirror';

  int get _parameterCount => _requiredParameterCount + _optionalParameterCount;

  List<ParameterMirror> get parameters {
    if (_parameters != null) return _parameters;
    metadata; // Compute _parameters as a side-effect of extracting metadata.
    return _parameters;
  }

  bool canInvokeReflectively() {
    return hasReflectableProperty(_jsFunction);
  }

  DeclarationMirror get owner => _owner;

  TypeMirror get returnType {
    metadata; // Compute _returnType as a side-effect of extracting metadata.
    return _returnType;
  }

  List<InstanceMirror> get metadata {
    if (_metadata == null) {
      var raw = extractMetadata(_jsFunction);
      var formals = new List(_parameterCount);
      ReflectionInfo info = new ReflectionInfo(_jsFunction);
      if (info != null) {
        assert(_parameterCount ==
            info.requiredParameterCount + info.optionalParameterCount);
        var functionType = info.functionType;
        var type;
        if (functionType is int) {
          type = new JsFunctionTypeMirror(info.computeFunctionRti(null), this);
          assert(_parameterCount == type.parameters.length);
        } else if (isTopLevel) {
          type = new JsFunctionTypeMirror(info.computeFunctionRti(null), owner);
        } else {
          TypeMirror ownerType = owner;
          JsClassMirror ownerClass = ownerType.originalDeclaration;
          type = new JsFunctionTypeMirror(
              info.computeFunctionRti(ownerClass._jsConstructor), owner);
        }
        // Constructors aren't reified with their return type.
        if (isConstructor) {
          _returnType = owner;
        } else {
          _returnType = type.returnType;
        }
        int i = 0;
        bool isNamed = info.areOptionalParametersNamed;
        for (JsParameterMirror parameter in type.parameters) {
          var name = info.parameterName(i);
          List<int> annotations = info.parameterMetadataAnnotations(i);
          var p;
          if (i < info.requiredParameterCount) {
            p = new JsParameterMirror(name, this, parameter._type,
                metadataList: annotations);
          } else {
            var defaultValue = info.defaultValue(i);
            p = new JsParameterMirror(name, this, parameter._type,
                metadataList: annotations,
                isOptional: true,
                isNamed: isNamed,
                defaultValue: defaultValue);
          }
          formals[i++] = p;
        }
      }
      _parameters = new UnmodifiableListView<ParameterMirror>(formals);
      _metadata = new UnmodifiableListView(raw.map(reflect));
    }
    return _metadata;
  }

  Symbol get constructorName {
    // TODO(ahe): I believe it is more appropriate to throw an exception or
    // return null.
    if (!isConstructor) return const Symbol('');
    String name = n(simpleName);
    int index = name.indexOf('.');
    if (index == -1) return const Symbol('');
    return s(name.substring(index + 1));
  }

  _invoke(List positionalArguments, Map<Symbol, dynamic> namedArguments) {
    if (namedArguments != null && !namedArguments.isEmpty) {
      throw new UnsupportedError('Named arguments are not implemented.');
    }
    if (!isStatic && !isConstructor) {
      throw new RuntimeError('Cannot invoke instance method without receiver.');
    }
    int positionalLength = positionalArguments.length;
    if (positionalLength < _requiredParameterCount ||
        positionalLength > _parameterCount ||
        _jsFunction == null) {
      // TODO(ahe): What receiver to use?
      throw new NoSuchMethodError(
          owner, simpleName, positionalArguments, namedArguments);
    }
    if (positionalLength < _parameterCount) {
      // Fill up with default values.
      // Make a copy so we don't modify the input.
      positionalArguments = positionalArguments.toList();
      for (int i = positionalLength; i < parameters.length; i++) {
        JsParameterMirror parameter = parameters[i];
        positionalArguments.add(parameter.defaultValue.reflectee);
      }
    }
    // Using JS_GET_STATIC_STATE() ('$') here is actually correct, although
    // _jsFunction may not be a property of '$', most static functions do not
    // care who their receiver is. But to lazy getters, it is important that
    // 'this' is '$'.
    return JS('', r'#.apply(#, #)', _jsFunction, JS_GET_STATIC_STATE(),
        new List.from(positionalArguments));
  }

  _getField(JsMirror receiver) {
    if (isGetter) {
      return _invoke([], null);
    } else {
      // TODO(ahe): Closurize method.
      throw new UnimplementedError('getField on $receiver');
    }
  }

  _setField(JsMirror receiver, Object arg) {
    if (isSetter) {
      return _invoke([arg], null);
    } else {
      throw new NoSuchMethodError(this, setterSymbol(simpleName), [], null);
    }
  }

  // Abstract methods are tree-shaken away.
  bool get isAbstract => false;

  // TODO(ahe, 14633): This might not be true for all cases.
  bool get isSynthetic => false;

  // TODO(ahe): Test this.
  bool get isRegularMethod => !isGetter && !isSetter && !isConstructor;

  // TODO(ahe): Implement this method.
  bool get isConstConstructor => throw new UnimplementedError();

  // TODO(ahe): Implement this method.
  bool get isGenerativeConstructor => throw new UnimplementedError();

  // TODO(ahe): Implement this method.
  bool get isRedirectingConstructor => throw new UnimplementedError();

  // TODO(ahe): Implement this method.
  bool get isFactoryConstructor => throw new UnimplementedError();

  // TODO(ahe): Implement this method.
  String get source => throw new UnimplementedError();
}

class JsParameterMirror extends JsDeclarationMirror implements ParameterMirror {
  final DeclarationMirror owner;
  // A JS object representing the type.
  final _type;

  final bool isOptional;

  final bool isNamed;

  final int _defaultValue;

  final List<int> metadataList;

  JsParameterMirror(String unmangledName, this.owner, this._type,
      {this.metadataList: const <int>[],
      this.isOptional: false,
      this.isNamed: false,
      defaultValue})
      : _defaultValue = defaultValue,
        super(s(unmangledName));

  String get _prettyName => 'ParameterMirror';

  TypeMirror get type {
    return typeMirrorFromRuntimeTypeRepresentation(owner, _type);
  }

  // Only true for static fields, never for a parameter.
  bool get isStatic => false;

  // TODO(ahe): Implement this.
  bool get isFinal => false;

  // TODO(ahe): Implement this.
  bool get isConst => false;

  bool get hasDefaultValue => _defaultValue != null;

  get defaultValue {
    return hasDefaultValue ? reflect(getMetadata(_defaultValue)) : null;
  }

  List<InstanceMirror> get metadata {
    preserveMetadata();
    return metadataList.map((int i) => reflect(getMetadata(i))).toList();
  }
}

class JsTypedefMirror extends JsDeclarationMirror implements TypedefMirror {
  final String _mangledName;
  JsFunctionTypeMirror referent;

  JsTypedefMirror(Symbol simpleName, this._mangledName, _typeData)
      : super(simpleName) {
    referent = new JsFunctionTypeMirror(_typeData, this);
  }

  JsFunctionTypeMirror get value => referent;

  String get _prettyName => 'TypedefMirror';

  bool get hasReflectedType => throw new UnimplementedError();

  Type get reflectedType => createRuntimeType(_mangledName);

  // TODO(floitsch): Implement this method.
  List<TypeVariableMirror> get typeVariables => throw new UnimplementedError();

  // TODO(floitsch): Implement this method.
  List<TypeMirror> get typeArguments => throw new UnimplementedError();

  bool get isOriginalDeclaration => true;

  TypeMirror get originalDeclaration => this;

  // TODO(floitsch): Implement this method.
  DeclarationMirror get owner => throw new UnimplementedError();

  // TODO(ahe): Implement this method.
  List<InstanceMirror> get metadata => throw new UnimplementedError();

  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();
}

// TODO(ahe): Remove this class when API is updated.
class BrokenClassMirror {
  bool get hasReflectedType => throw new UnimplementedError();
  Type get reflectedType => throw new UnimplementedError();
  ClassMirror get superclass => throw new UnimplementedError();
  List<ClassMirror> get superinterfaces => throw new UnimplementedError();
  Map<Symbol, DeclarationMirror> get declarations =>
      throw new UnimplementedError();
  Map<Symbol, MethodMirror> get instanceMembers =>
      throw new UnimplementedError();
  Map<Symbol, MethodMirror> get staticMembers => throw new UnimplementedError();
  ClassMirror get mixin => throw new UnimplementedError();
  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
          [Map<Symbol, dynamic> namedArguments]) =>
      throw new UnimplementedError();
  InstanceMirror invoke(Symbol memberName, List positionalArguments,
          [Map<Symbol, dynamic> namedArguments]) =>
      throw new UnimplementedError();
  InstanceMirror getField(Symbol fieldName) => throw new UnimplementedError();
  InstanceMirror setField(Symbol fieldName, Object value) =>
      throw new UnimplementedError();
  delegate(Invocation invocation) => throw new UnimplementedError();
  List<TypeVariableMirror> get typeVariables => throw new UnimplementedError();
  List<TypeMirror> get typeArguments => throw new UnimplementedError();
  TypeMirror get originalDeclaration => throw new UnimplementedError();
  Symbol get simpleName => throw new UnimplementedError();
  Symbol get qualifiedName => throw new UnimplementedError();
  bool get isPrivate => throw new UnimplementedError();
  bool get isTopLevel => throw new UnimplementedError();
  SourceLocation get location => throw new UnimplementedError();
  List<InstanceMirror> get metadata => throw new UnimplementedError();
}

class JsFunctionTypeMirror extends BrokenClassMirror
    implements FunctionTypeMirror {
  final _typeData;
  String _cachedToString;
  TypeMirror _cachedReturnType;
  UnmodifiableListView<ParameterMirror> _cachedParameters;
  Type _cachedReflectedType;
  DeclarationMirror owner;

  JsFunctionTypeMirror(this._typeData, this.owner);

  bool get _hasReturnType {
    return JS('bool', '# in #',
        JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG), _typeData);
  }

  get _returnType {
    return JS('', '#[#]', _typeData,
        JS_GET_NAME(JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG));
  }

  bool get _isVoid {
    return JS('bool', '!!#[#]', _typeData,
        JS_GET_NAME(JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG));
  }

  bool get _hasArguments {
    return JS(
        'bool',
        '# in #',
        JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG),
        _typeData);
  }

  List get _arguments {
    return JS('JSExtendableArray', '#[#]', _typeData,
        JS_GET_NAME(JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG));
  }

  bool get _hasOptionalArguments {
    return JS(
        'bool',
        '# in #',
        JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG),
        _typeData);
  }

  List get _optionalArguments {
    return JS('JSExtendableArray', '#[#]', _typeData,
        JS_GET_NAME(JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG));
  }

  bool get _hasNamedArguments {
    return JS('bool', '# in #',
        JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG), _typeData);
  }

  get _namedArguments {
    return JS('=Object', '#[#]', _typeData,
        JS_GET_NAME(JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG));
  }

  bool get isOriginalDeclaration => true;

  bool get isAbstract => false;

  bool get isEnum => false;

  TypeMirror get returnType {
    if (_cachedReturnType != null) return _cachedReturnType;
    if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType;
    if (!_hasReturnType) return _cachedReturnType = JsMirrorSystem._dynamicType;
    return _cachedReturnType =
        typeMirrorFromRuntimeTypeRepresentation(owner, _returnType);
  }

  List<ParameterMirror> get parameters {
    if (_cachedParameters != null) return _cachedParameters;
    List result = [];
    int parameterCount = 0;
    if (_hasArguments) {
      for (var type in _arguments) {
        result.add(
            new JsParameterMirror('argument${parameterCount++}', this, type));
      }
    }
    if (_hasOptionalArguments) {
      for (var type in _optionalArguments) {
        result.add(
            new JsParameterMirror('argument${parameterCount++}', this, type));
      }
    }
    if (_hasNamedArguments) {
      for (var name in extractKeys(_namedArguments)) {
        var type = JS('', '#[#]', _namedArguments, name);
        result.add(new JsParameterMirror(name, this, type));
      }
    }
    return _cachedParameters =
        new UnmodifiableListView<ParameterMirror>(result);
  }

  bool get hasReflectedType => true;
  Type get reflectedType => _cachedReflectedType ??=
      createRuntimeType(runtimeTypeToString(_typeData));

  String _unmangleIfPreserved(String mangled) {
    String result = unmangleGlobalNameIfPreservedAnyways(mangled);
    if (result != null) return result;
    return mangled;
  }

  String toString() {
    if (_cachedToString != null) return _cachedToString;
    var s = "FunctionTypeMirror on '(";
    var sep = '';
    if (_hasArguments) {
      for (var argument in _arguments) {
        s += sep;
        s += _unmangleIfPreserved(runtimeTypeToString(argument));
        sep = ', ';
      }
    }
    if (_hasOptionalArguments) {
      s += '$sep[';
      sep = '';
      for (var argument in _optionalArguments) {
        s += sep;
        s += _unmangleIfPreserved(runtimeTypeToString(argument));
        sep = ', ';
      }
      s += ']';
    }
    if (_hasNamedArguments) {
      s += '$sep{';
      sep = '';
      for (var name in extractKeys(_namedArguments)) {
        s += sep;
        s += '$name: ';
        s += _unmangleIfPreserved(
            runtimeTypeToString(JS('', '#[#]', _namedArguments, name)));
        sep = ', ';
      }
      s += '}';
    }
    s += ') -> ';
    if (_isVoid) {
      s += 'void';
    } else if (_hasReturnType) {
      s += _unmangleIfPreserved(runtimeTypeToString(_returnType));
    } else {
      s += 'dynamic';
    }
    return _cachedToString = "$s'";
  }

  bool isSubclassOf(ClassMirror other) => false;

  bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();

  bool isAssignableTo(TypeMirror other) => throw new UnimplementedError();

  // TODO(ahe): Implement this method.
  MethodMirror get callMethod => throw new UnimplementedError();
}

int findTypeVariableIndex(List<TypeVariableMirror> typeVariables, String name) {
  for (int i = 0; i < typeVariables.length; i++) {
    if (typeVariables[i].simpleName == s(name)) {
      return i;
    }
  }
  throw new ArgumentError('Type variable not present in list.');
}

TypeMirror typeMirrorFromRuntimeTypeRepresentation(
    DeclarationMirror owner, var /*int|List|JsFunction|TypeImpl*/ type) {
  // TODO(ahe): This method might benefit from using convertRtiToRuntimeType
  // instead of working on strings.
  if (type == null) {
    return JsMirrorSystem._dynamicType;
  }

  ClassMirror ownerClass;
  DeclarationMirror context = owner;
  while (context != null) {
    if (context is ClassMirror) {
      ownerClass = context;
      break;
    }
    // TODO(ahe): Get type parameters and arguments from typedefs.
    if (context is TypedefMirror) break;
    context = context.owner;
  }

  String representation;
  if (type is TypeImpl) {
    return reflectType(type);
  } else if (ownerClass == null) {
    representation = runtimeTypeToString(type);
  } else if (ownerClass.isOriginalDeclaration) {
    if (type is num) {
      // [type] represents a type variable so in the context of an original
      // declaration the corresponding type variable should be returned.
      TypeVariable typeVariable = getMetadata(type);
      List<TypeVariableMirror> typeVariables = ownerClass.typeVariables;
      int index = findTypeVariableIndex(typeVariables, typeVariable.name);
      return typeVariables[index];
    } else {
      // Nested type variables will be retrieved lazily (the integer
      // representation is kept in the string) so they are not processed here.
      representation = runtimeTypeToString(type);
    }
  } else {
    TypeMirror getTypeArgument(int index) {
      TypeVariable typeVariable = getMetadata(index);
      int variableIndex =
          findTypeVariableIndex(ownerClass.typeVariables, typeVariable.name);
      return ownerClass.typeArguments[variableIndex];
    }

    if (type is num) {
      // [type] represents a type variable used as type argument for example
      // the type argument of Bar: class Foo<T> extends Bar<T> {}
      TypeMirror typeArgument = getTypeArgument(type);
      if (typeArgument is JsTypeVariableMirror) return typeArgument;
    }
    String substituteTypeVariable(int index) {
      var typeArgument = getTypeArgument(index);
      if (typeArgument is JsTypeVariableMirror) {
        return '${typeArgument._metadataIndex}';
      }
      if (typeArgument is! JsClassMirror &&
          typeArgument is! JsTypeBoundClassMirror) {
        if (typeArgument == JsMirrorSystem._dynamicType) {
          return 'dynamic';
        } else if (typeArgument == JsMirrorSystem._voidType) {
          return 'void';
        } else {
          // TODO(ahe): This case shouldn't happen.
          return 'dynamic';
        }
      }
      return typeArgument._mangledName;
    }

    representation =
        runtimeTypeToString(type, onTypeVariable: substituteTypeVariable);
  }
  if (representation != null) {
    return reflectClassByMangledName(
        getMangledTypeName(createRuntimeType(representation)));
  }
  String typedefPropertyName = JS_GET_NAME(JsGetName.TYPEDEF_TAG);
  if (JS('', '#[#]', type, typedefPropertyName) != null) {
    return typeMirrorFromRuntimeTypeRepresentation(
        owner, JS('', '#[#]', type, typedefPropertyName));
  } else if (isDartFunctionType(type)) {
    return new JsFunctionTypeMirror(type, owner);
  }
  return reflectClass(Function);
}

Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
  if (owner == null) return simpleName;
  String ownerName = n(owner.qualifiedName);
  return s('$ownerName.${n(simpleName)}');
}

List extractMetadata(victim) {
  preserveMetadata();
  var metadataFunction;
  if (JS('bool', 'Object.prototype.hasOwnProperty.call(#, "@")', victim)) {
    metadataFunction = JS('', '#["@"]', victim);
  }
  if (metadataFunction != null) return JS('', '#()', metadataFunction);
  if (JS('bool', 'typeof # != "function"', victim)) return const [];
  if (JS('bool', '# in #', r'$metadataIndex', victim)) {
    return JSArray
        .markFixedList(JS('JSExtendableArray',
            r'#.$reflectionInfo.splice(#.$metadataIndex)', victim, victim))
        .map((int i) => getMetadata(i))
        .toList();
  }
  return const [];
}

void parseCompactFieldSpecification(JsDeclarationMirror owner,
    fieldSpecification, bool isStatic, List<Mirror> result) {
  List fieldsMetadata = null;
  List<String> fields;
  if (fieldSpecification is List) {
    fields = splitFields(fieldSpecification[0], ',');
    fieldsMetadata = fieldSpecification.sublist(1);
  } else if (fieldSpecification is String) {
    fields = splitFields(fieldSpecification, ',');
  } else {
    fields = [];
  }
  int fieldNumber = 0;
  for (String field in fields) {
    if (r'$ti' == field) continue; // Strip type info pseudofield.
    var metadata;
    if (fieldsMetadata != null) {
      metadata = fieldsMetadata[fieldNumber++];
    }
    var mirror = new JsVariableMirror.from(field, metadata, owner, isStatic);
    if (mirror != null) {
      result.add(mirror);
    }
  }
}

/// Similar to [String.split], but returns an empty list if [string] is empty.
List<String> splitFields(String string, Pattern pattern) {
  if (string.isEmpty) return <String>[];
  return string.split(pattern);
}

bool isOperatorName(String name) {
  switch (name) {
    case '==':
    case '[]':
    case '*':
    case '/':
    case '%':
    case '~/':
    case '+':
    case '<<':
    case '>>':
    case '>=':
    case '>':
    case '<=':
    case '<':
    case '&':
    case '^':
    case '|':
    case '-':
    case 'unary-':
    case '[]=':
    case '~':
      return true;
    default:
      return false;
  }
}

/// Returns true if the key represent ancillary reflection data, that is, not a
/// method.
bool isReflectiveDataInPrototype(String key) {
  if (key == JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY) ||
      key == METHODS_WITH_OPTIONAL_ARGUMENTS) {
    return true;
  }
  String firstChar = key[0];
  return firstChar == '*' || firstChar == '+';
}

/// Returns `true` if [jsFunction] is an ordinary reflectable method and
/// not a (potentially reflectable) stub or otherwise non-reflectable method.
bool isOrdinaryReflectableMethod(var jsFunction) {
  return JS('bool', r'#.$reflectable === 1', jsFunction);
}

/// Returns true if [key] is only an aliased entry for [function] in the
/// prototype.
bool isAliasedSuperMethod(var jsFunction, String key) {
  var stubName = JS('String|Null', r'#.$stubName', jsFunction);
  return stubName != null && key != stubName;
}

class NoSuchStaticMethodError extends Error implements NoSuchMethodError {
  static const int MISSING_CONSTRUCTOR = 0;
  static const int MISSING_METHOD = 1;
  final ClassMirror _cls;
  final Symbol _name;
  final List _positionalArguments;
  final Map<Symbol, dynamic> _namedArguments;
  final int _kind;

  NoSuchStaticMethodError.missingConstructor(
      this._cls, this._name, this._positionalArguments, this._namedArguments)
      : _kind = MISSING_CONSTRUCTOR;

  /// If the given class is `null` the static method/getter/setter is top-level.
  NoSuchStaticMethodError.method(
      this._cls, this._name, this._positionalArguments, this._namedArguments)
      : _kind = MISSING_METHOD;

  String toString() {
    // TODO(floitsch): show arguments.
    switch (_kind) {
      case MISSING_CONSTRUCTOR:
        return "NoSuchMethodError: No constructor named '${n(_name)}' in class"
            " '${n(_cls.qualifiedName)}'.";
      case MISSING_METHOD:
        if (_cls == null) {
          return "NoSuchMethodError: No top-level method named '${n(_name)}'.";
        }
        return "NoSuchMethodError: No static method named '${n(_name)}' in"
            " class '${n(_cls.qualifiedName)}'";
      default:
        return 'NoSuchMethodError';
    }
  }
}

Symbol getSymbol(String name, LibraryMirror library) {
  if (_isPublicSymbol(name)) {
    return new _symbol_dev.Symbol.validated(name);
  }
  if (library == null) {
    throw new ArgumentError('Library required for private symbol name: $name');
  }
  if (!_symbol_dev.Symbol.isValidSymbol(name)) {
    throw new ArgumentError('Not a valid symbol name: $name');
  }
  throw new UnimplementedError(
      'MirrorSystem.getSymbol not implemented for private names');
}

bool _isPublicSymbol(String name) {
  // A symbol is public if it doesn't start with '_' and it doesn't
  // have a part (following a '.') that starts with '_'.
  const int UNDERSCORE = 0x5f;
  if (name.isEmpty) return true;
  int index = -1;
  do {
    if (name.codeUnitAt(index + 1) == UNDERSCORE) return false;
    index = name.indexOf('.', index + 1);
  } while (index >= 0 && index + 1 < name.length);
  return true;
}
