// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library _js_helper;

import 'dart:collection';
import 'dart:_foreign_helper' show DART_CLOSURE_TO_JS,
                                   JS,
                                   JS_CALL_IN_ISOLATE,
                                   JS_CURRENT_ISOLATE,
                                   JS_DART_OBJECT_CONSTRUCTOR,
                                   JS_OPERATOR_IS_PREFIX,
                                   JS_OPERATOR_AS_PREFIX,
                                   JS_HAS_EQUALS,
                                   RAW_DART_FUNCTION_REF,
                                   UNINTERCEPTED;
import 'dart:_interceptors' show getInterceptor,
                                 interceptedNames;

part 'constant_map.dart';
part 'native_helper.dart';
part 'regexp_helper.dart';
part 'string_helper.dart';

bool isJsArray(var value) {
  return value != null && JS('bool', r'(#.constructor === Array)', value);
}

checkMutable(list, reason) {
  if (JS('bool', r'!!(#.immutable$list)', list)) {
    throw new UnsupportedError(reason);
  }
}

checkGrowable(list, reason) {
  if (JS('bool', r'!!(#.fixed$length)', list)) {
    throw new UnsupportedError(reason);
  }
}

String S(value) {
  if (value is String) return value;
  if ((value is num && value != 0) || value is bool) {
    return JS('String', r'String(#)', value);
  }
  if (value == null) return 'null';
  var res = value.toString();
  if (res is !String) throw new ArgumentError(value);
  return res;
}

createInvocationMirror(name, internalName, type, arguments, argumentNames) =>
    new JSInvocationMirror(name, internalName, type, arguments, argumentNames);

class JSInvocationMirror implements InvocationMirror {
  static const METHOD = 0;
  static const GETTER = 1;
  static const SETTER = 2;

  final String memberName;
  final String _internalName;
  final int _kind;
  final List _arguments;
  final List _namedArgumentNames;
  /** Map from argument name to index in _arguments. */
  Map<String,dynamic> _namedIndices = null;

  JSInvocationMirror(this.memberName,
                     this._internalName,
                     this._kind,
                     this._arguments,
                     this._namedArgumentNames);

  bool get isMethod => _kind == METHOD;
  bool get isGetter => _kind == GETTER;
  bool get isSetter => _kind == SETTER;
  bool get isAccessor => _kind != METHOD;

  List get positionalArguments {
    if (isGetter) return null;
    var list = [];
    var argumentCount =
        _arguments.length - _namedArgumentNames.length;
    for (var index = 0 ; index < argumentCount ; index++) {
      list.add(_arguments[index]);
    }
    return list;
  }

  Map<String,dynamic> get namedArguments {
    if (isAccessor) return null;
    var map = <String,dynamic>{};
    int namedArgumentCount = _namedArgumentNames.length;
    int namedArgumentsStartIndex = _arguments.length - namedArgumentCount;
    for (int i = 0; i < namedArgumentCount; i++) {
      map[_namedArgumentNames[i]] = _arguments[namedArgumentsStartIndex + i];
    }
    return map;
  }

  invokeOn(Object object) {
    var interceptor = getInterceptor(object);
    var receiver = object;
    var name = _internalName;
    var arguments = _arguments;
    // TODO(ngeoffray): If this functionality ever become performance
    // critical, we might want to dynamically change [interceptedNames]
    // to be a JavaScript object with intercepted names as property
    // instead of a JavaScript array.
    if (JS('int', '#.indexOf(#)', interceptedNames, name) == -1) {
      if (!isJsArray(arguments)) arguments = new List.from(arguments);
    } else {
      arguments = [object]..addAll(arguments);
      receiver = interceptor;
    }
    return JS("var", "#[#].apply(#, #)", receiver, name, receiver, arguments);
  }
}

class Primitives {
  static int hashCodeSeed = 0;

  static int objectHashCode(object) {
    int hash = JS('var', r'#.$identityHash', object);
    if (hash == null) {
      // TOOD(ahe): We should probably randomize this somehow.
      hash = ++hashCodeSeed;
      JS('void', r'#.$identityHash = #', object, hash);
    }
    return hash;
  }

  /**
   * This is the low-level method that is used to implement
   * [print]. It is possible to override this function from JavaScript
   * by defining a function in JavaScript called "dartPrint".
   */
  static void printString(String string) {
    if (JS('bool', r'typeof dartPrint == "function"')) {
      // Support overriding print from JavaScript.
      JS('void', r'dartPrint(#)', string);
      return;
    }

    // Inside browser.
    if (JS('bool', r'typeof window == "object"')) {
      // On IE, the console is only defined if dev tools is open.
      if (JS('bool', r'typeof console == "object"')) {
        JS('void', r'console.log(#)', string);
      }
      return;
    }

    // Running in d8, the V8 developer shell, or in Firefox' js-shell.
    if (JS('bool', r'typeof print == "function"')) {
      JS('void', r'print(#)', string);
      return;
    }

    // This is somewhat nasty, but we don't want to drag in a bunch of
    // dependencies to handle a situation that cannot happen. So we
    // avoid using Dart [:throw:] and Dart [toString].
    JS('void', 'throw "Unable to print message: " + String(#)', string);
  }

  static void _throwFormatException(String string) {
    throw new FormatException(string);
  }

  static int parseInt(String source,
                      int radix,
                      int handleError(String source)) {
    if (handleError == null) handleError = _throwFormatException;

    checkString(source);
    var match = JS('=List|Null',
        r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i.exec(#)',
        source);
    int digitsIndex = 1;
    int hexIndex = 2;
    int decimalIndex = 3;
    int nonDecimalHexIndex = 4;
    if (radix == null) {
      radix = 10;
      if (match != null) {
        if (match[hexIndex] != null) {
          // Cannot fail because we know that the digits are all hex.
          return JS('num', r'parseInt(#, 16)', source);
        }
        if (match[decimalIndex] != null) {
          // Cannot fail because we know that the digits are all decimal.
          return JS('num', r'parseInt(#, 10)', source);
        }
        return handleError(source);
      }
    } else {
      if (radix is! int) throw new ArgumentError("Radix is not an integer");
      if (radix < 2 || radix > 36) {
        throw new RangeError("Radix $radix not in range 2..36");
      }
      if (match != null) {
        if (radix == 10 && match[decimalIndex] != null) {
          // Cannot fail because we know that the digits are all decimal.
          return JS('num', r'parseInt(#, 10)', source);
        }
        if (radix < 10 || match[decimalIndex] == null) {
          // We know that the characters must be ASCII as otherwise the
          // regexp wouldn't have matched. Calling toLowerCase is thus
          // guaranteed to be a safe operation. If it wasn't ASCII, then
          // "İ" would become "i", and we would accept it for radices greater
          // than 18.
          int maxCharCode;
          if (radix <= 10) {
            // Allow all digits less than the radix. For example 0, 1, 2 for
            // radix 3.
            // "0".codeUnitAt(0) + radix - 1;
            maxCharCode = 0x30 + radix - 1;
          } else {
            // Characters are located after the digits in ASCII. Therefore we
            // only check for the character code. The regexp above made already
            // sure that the string does not contain anything but digits or
            // characters.
            // "0".codeUnitAt(0) + radix - 1;
            maxCharCode = 0x61 + radix - 10 - 1;
          }
          String digitsPart = match[digitsIndex].toLowerCase();
          for (int i = 0; i < digitsPart.length; i++) {
            if (digitsPart.codeUnitAt(i) > maxCharCode) {
              return handleError(source);
            }
          }
        }
      }
    }
    if (match == null) return handleError(source);
    return JS('num', r'parseInt(#, #)', source, radix);
  }

  static double parseDouble(String source, int handleError(String source)) {
    checkString(source);
    if (handleError == null) handleError = _throwFormatException;
    // Notice that JS parseFloat accepts garbage at the end of the string.
    // Accept only:
    // - NaN
    // - [+/-]Infinity
    // - a Dart double literal
    // We do not allow leading or trailing whitespace.
    if (!JS('bool',
            r'/^\s*(?:NaN|[+-]?(?:Infinity|'
                r'(?:\.\d+|\d+(?:\.\d+)?)(?:[eE][+-]?\d+)?))\s*$/.test(#)',
            source)) {
      return handleError(source);
    }
    var result = JS('num', r'parseFloat(#)', source);
    if (result.isNaN && source != 'NaN') {
      return handleError(source);
    }
    return result;
  }

  /** [: r"$".codeUnitAt(0) :] */
  static const int DOLLAR_CHAR_VALUE = 36;

  static String objectTypeName(Object object) {
    String name = constructorNameFallback(object);
    if (name == 'Object') {
      // Try to decompile the constructor by turning it into a string
      // and get the name out of that. If the decompiled name is a
      // string, we use that instead of the very generic 'Object'.
      var decompiled = JS('var', r'#.match(/^\s*function\s*(\S*)\s*\(/)[1]',
                          JS('var', r'String(#.constructor)', object));
      if (decompiled is String) name = decompiled;
    }
    // TODO(kasperl): If the namer gave us a fresh global name, we may
    // want to remove the numeric suffix that makes it unique too.
    if (identical(name.codeUnitAt(0), DOLLAR_CHAR_VALUE)) name = name.substring(1);
    return name;
  }

  static String objectToString(Object object) {
    String name = objectTypeName(object);
    return "Instance of '$name'";
  }

  static List newGrowableList(length) {
    return JS('=List', r'new Array(#)', length);
  }

  static List newFixedList(length) {
    var result = JS('=List', r'new Array(#)', length);
    JS('void', r'#.fixed$length = #', result, true);
    return result;
  }

  static num dateNow() => JS('num', r'Date.now()');

  static num numMicroseconds() {
    if (JS('bool', 'typeof window != "undefined" && window !== null')) {
      var performance = JS('var', 'window.performance');
      if (performance != null &&
          JS('bool', 'typeof #.webkitNow == "function"', performance)) {
        return (1000 * JS('num', '#.webkitNow()', performance)).floor();
      }
    }
    return 1000 * dateNow();
  }

  // This is to avoid stack overflows due to very large argument arrays in
  // apply().  It fixes http://dartbug.com/6919
  static String _fromCharCodeApply(List<int> array) {
    String result = "";
    const kMaxApply = 500;
    int end = array.length;
    for (var i = 0; i < end; i += kMaxApply) {
      var subarray;
      if (end <= kMaxApply) {
        subarray = array;
      } else {
        subarray = JS('=List', r'#.slice(#, #)', array,
                      i, i + kMaxApply < end ? i + kMaxApply : end);
      }
      result = JS('String', '# + String.fromCharCode.apply(#, #)',
                  result, null, subarray);
    }
    return result;
  }

  static String stringFromCodePoints(codePoints) {
    List<int> a = <int>[];
    for (var i in codePoints) {
      if (i is !int) throw new ArgumentError(i);
      if (i <= 0xffff) {
        a.add(i);
      } else if (i <= 0x10ffff) {
        a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff)));
        a.add(0xdc00 + (i & 0x3ff));
      } else {
        throw new ArgumentError(i);
      }
    }
    return _fromCharCodeApply(a);
  }

  static String stringFromCharCodes(charCodes) {
    for (var i in charCodes) {
      if (i is !int) throw new ArgumentError(i);
      if (i < 0) throw new ArgumentError(i);
      if (i > 0xffff) return stringFromCodePoints(charCodes);
    }
    return _fromCharCodeApply(charCodes);
  }

  static String stringConcatUnchecked(String string1, String string2) {
    return JS('String', r'# + #', string1, string2);
  }

  static String getTimeZoneName(receiver) {
    // When calling toString on a Date it will emit the timezone in parenthesis.
    // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)".
    // We extract this name using a regexp.
    var d = lazyAsJsDate(receiver);
    return JS('String', r'/\((.*)\)/.exec(#.toString())[1]', d);
  }

  static int getTimeZoneOffsetInMinutes(receiver) {
    // Note that JS and Dart disagree on the sign of the offset.
    return -JS('int', r'#.getTimezoneOffset()', lazyAsJsDate(receiver));
  }

  static valueFromDecomposedDate(years, month, day, hours, minutes, seconds,
                                 milliseconds, isUtc) {
    final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
    checkInt(years);
    checkInt(month);
    checkInt(day);
    checkInt(hours);
    checkInt(minutes);
    checkInt(seconds);
    checkInt(milliseconds);
    checkBool(isUtc);
    var jsMonth = month - 1;
    var value;
    if (isUtc) {
      value = JS('num', r'Date.UTC(#, #, #, #, #, #, #)',
                 years, jsMonth, day, hours, minutes, seconds, milliseconds);
    } else {
      value = JS('num', r'new Date(#, #, #, #, #, #, #).valueOf()',
                 years, jsMonth, day, hours, minutes, seconds, milliseconds);
    }
    if (value.isNaN ||
        value < -MAX_MILLISECONDS_SINCE_EPOCH ||
        value > MAX_MILLISECONDS_SINCE_EPOCH) {
      throw new ArgumentError();
    }
    if (years <= 0 || years < 100) return patchUpY2K(value, years, isUtc);
    return value;
  }

  static patchUpY2K(value, years, isUtc) {
    var date = JS('', r'new Date(#)', value);
    if (isUtc) {
      JS('num', r'#.setUTCFullYear(#)', date, years);
    } else {
      JS('num', r'#.setFullYear(#)', date, years);
    }
    return JS('num', r'#.valueOf()', date);
  }

  // Lazily keep a JS Date stored in the JS object.
  static lazyAsJsDate(receiver) {
    if (JS('bool', r'#.date === (void 0)', receiver)) {
      JS('void', r'#.date = new Date(#)', receiver,
         receiver.millisecondsSinceEpoch);
    }
    return JS('var', r'#.date', receiver);
  }

  // The getters for date and time parts below add a positive integer to ensure
  // that the result is really an integer, because the JavaScript implementation
  // may return -0.0 instead of 0.

  static getYear(receiver) {
    return (receiver.isUtc)
      ? JS('int', r'(#.getUTCFullYear() + 0)', lazyAsJsDate(receiver))
      : JS('int', r'(#.getFullYear() + 0)', lazyAsJsDate(receiver));
  }

  static getMonth(receiver) {
    return (receiver.isUtc)
      ? JS('int', r'#.getUTCMonth() + 1', lazyAsJsDate(receiver))
      : JS('int', r'#.getMonth() + 1', lazyAsJsDate(receiver));
  }

  static getDay(receiver) {
    return (receiver.isUtc)
      ? JS('int', r'(#.getUTCDate() + 0)', lazyAsJsDate(receiver))
      : JS('int', r'(#.getDate() + 0)', lazyAsJsDate(receiver));
  }

  static getHours(receiver) {
    return (receiver.isUtc)
      ? JS('int', r'(#.getUTCHours() + 0)', lazyAsJsDate(receiver))
      : JS('int', r'(#.getHours() + 0)', lazyAsJsDate(receiver));
  }

  static getMinutes(receiver) {
    return (receiver.isUtc)
      ? JS('int', r'(#.getUTCMinutes() + 0)', lazyAsJsDate(receiver))
      : JS('int', r'(#.getMinutes() + 0)', lazyAsJsDate(receiver));
  }

  static getSeconds(receiver) {
    return (receiver.isUtc)
      ? JS('int', r'(#.getUTCSeconds() + 0)', lazyAsJsDate(receiver))
      : JS('int', r'(#.getSeconds() + 0)', lazyAsJsDate(receiver));
  }

  static getMilliseconds(receiver) {
    return (receiver.isUtc)
      ? JS('int', r'(#.getUTCMilliseconds() + 0)', lazyAsJsDate(receiver))
      : JS('int', r'(#.getMilliseconds() + 0)', lazyAsJsDate(receiver));
  }

  static getWeekday(receiver) {
    int weekday = (receiver.isUtc)
      ? JS('int', r'#.getUTCDay() + 0', lazyAsJsDate(receiver))
      : JS('int', r'#.getDay() + 0', lazyAsJsDate(receiver));
    // Adjust by one because JS weeks start on Sunday.
    return (weekday + 6) % 7 + 1;
  }

  static valueFromDateString(str) {
    if (str is !String) throw new ArgumentError(str);
    var value = JS('num', r'Date.parse(#)', str);
    if (value.isNaN) throw new ArgumentError(str);
    return value;
  }

  static getProperty(object, key) {
    if (object == null || object is bool || object is num || object is String) {
      throw new ArgumentError(object);
    }
    return JS('var', '#[#]', object, key);
  }

  static void setProperty(object, key, value) {
    if (object == null || object is bool || object is num || object is String) {
      throw new ArgumentError(object);
    }
    JS('void', '#[#] = #', object, key, value);
  }

  static applyFunction(Function function,
                       List positionalArguments,
                       Map<String, dynamic> namedArguments) {
    int argumentCount = 0;
    StringBuffer buffer = new StringBuffer();
    List arguments = [];

    if (positionalArguments != null) {
      argumentCount += positionalArguments.length;
      arguments.addAll(positionalArguments);
    }

    // Sort the named arguments to get the right selector name and
    // arguments order.
    if (namedArguments != null && !namedArguments.isEmpty) {
      // Call new List.from to make sure we get a JavaScript array.
      List<String> listOfNamedArguments =
          new List<String>.from(namedArguments.keys);
      argumentCount += namedArguments.length;
      // We're sorting on strings, and the behavior is the same between
      // Dart string sort and JS string sort. To avoid needing the Dart
      // sort implementation, we use the JavaScript one instead.
      JS('void', '#.sort()', listOfNamedArguments);
      listOfNamedArguments.forEach((String name) {
        buffer.add('\$$name');
        arguments.add(namedArguments[name]);
      });
    }

    String selectorName = 'call\$$argumentCount$buffer';
    var jsFunction = JS('var', '#[#]', function, selectorName);
    if (jsFunction == null) {
      throw new NoSuchMethodError(function, selectorName, arguments, {});
    }
    // We bound 'this' to [function] because of how we compile
    // closures: escaped local variables are stored and accessed through
    // [function].
    return JS('var', '#.apply(#, #)', jsFunction, function, arguments);
  }

  static getConstructor(String className) {
    // TODO(ahe): How to safely access $?
    return JS('var', r'$[#]', className);
  }

  static bool identicalImplementation(a, b) {
    return JS('bool', '# == null', a)
      ? JS('bool', '# == null', b)
      : JS('bool', '# === #', a, b);
  }
}

/**
 * Called by generated code to throw an illegal-argument exception,
 * for example, if a non-integer index is given to an optimized
 * indexed access.
 */
iae(argument) {
  throw new ArgumentError(argument);
}

/**
 * Called by generated code to throw an index-out-of-range exception,
 * for example, if a bounds check fails in an optimized indexed
 * access.
 */
ioore(index) {
  throw new RangeError.value(index);
}

stringLastIndexOfUnchecked(receiver, element, start)
  => JS('int', r'#.lastIndexOf(#, #)', receiver, element, start);


checkNull(object) {
  if (object == null) throw new ArgumentError(null);
  return object;
}

checkNum(value) {
  if (value is !num) {
    throw new ArgumentError(value);
  }
  return value;
}

checkInt(value) {
  if (value is !int) {
    throw new ArgumentError(value);
  }
  return value;
}

checkBool(value) {
  if (value is !bool) {
    throw new ArgumentError(value);
  }
  return value;
}

checkString(value) {
  if (value is !String) {
    throw new ArgumentError(value);
  }
  return value;
}

class MathNatives {
  static double sqrt(num value)
    => JS('double', r'Math.sqrt(#)', checkNum(value));

  static double sin(num value)
    => JS('double', r'Math.sin(#)', checkNum(value));

  static double cos(num value)
    => JS('double', r'Math.cos(#)', checkNum(value));

  static double tan(num value)
    => JS('double', r'Math.tan(#)', checkNum(value));

  static double acos(num value)
    => JS('double', r'Math.acos(#)', checkNum(value));

  static double asin(num value)
    => JS('double', r'Math.asin(#)', checkNum(value));

  static double atan(num value)
    => JS('double', r'Math.atan(#)', checkNum(value));

  static double atan2(num a, num b)
    => JS('double', r'Math.atan2(#, #)', checkNum(a), checkNum(b));

  static double exp(num value)
    => JS('double', r'Math.exp(#)', checkNum(value));

  static double log(num value)
    => JS('double', r'Math.log(#)', checkNum(value));

  static num pow(num value, num exponent) {
    checkNum(value);
    checkNum(exponent);
    return JS('num', r'Math.pow(#, #)', value, exponent);
  }

  static double random() => JS('double', r'Math.random()');
}

/**
 * Wrap the given Dart object and record a stack trace.
 *
 * The code in [unwrapException] deals with getting the original Dart
 * object out of the wrapper again.
 */
$throw(ex) {
  if (ex == null) ex = const NullThrownError();
  var wrapper = new DartError(ex);

  if (JS('bool', '!!Error.captureStackTrace')) {
    // Use V8 API for recording a "fast" stack trace (this installs a
    // "stack" property getter on [wrapper]).
    JS('void', r'Error.captureStackTrace(#, #)',
       wrapper, RAW_DART_FUNCTION_REF($throw));
  } else {
    // Otherwise, produce a stack trace and record it in the wrapper.
    // This is a slower way to create a stack trace which works on
    // some browsers, but may simply evaluate to null.
    String stackTrace = JS('', 'new Error().stack');
    JS('void', '#.stack = #', wrapper, stackTrace);
  }
  return wrapper;
}

/**
 * Wrapper class for throwing exceptions.
 */
class DartError {
  /// The Dart object (or primitive JavaScript value) which was thrown is
  /// attached to this object as a field named 'dartException'.  We do this
  /// only in raw JS so that we can use the 'in' operator and so that the
  /// minifier does not rename the field.  Therefore it is not declared as a
  /// real field.

  DartError(var dartException) {
    JS('void', '#.dartException = #', this, dartException);
    // Install a toString method that the JavaScript system will call
    // to format uncaught exceptions.
    JS('void', '#.toString = #', this, DART_CLOSURE_TO_JS(toStringWrapper));
  }

  /**
   * V8/Chrome installs a property getter, "stack", when calling
   * Error.captureStackTrace (see [$throw]). In [$throw], we make sure
   * that this property is always set.
   */
  String get stack => JS('', '#.stack', this);

  /**
   * This method can be invoked by calling toString from
   * JavaScript. See the constructor of this class.
   *
   * We only expect this method to be called (indirectly) by the
   * browser when an uncaught exception occurs. Instance of this class
   * should never escape into Dart code (except for [$throw] above).
   */
  String toString() {
    // If Error.captureStackTrace is available, accessing stack from
    // this method would cause recursion because the stack property
    // (on this object) is actually a getter which calls toString on
    // this object (via the wrapper installed in this class'
    // constructor). Fortunately, both Chrome and d8 prints the stack
    // trace and Chrome even applies source maps to the stack
    // trace. Remeber, this method is only ever invoked by the browser
    // when an uncaught exception occurs.
    var dartException = JS('var', r'#.dartException', this);
    if (JS('bool', '!!Error.captureStackTrace') || (stack == null)) {
      return dartException.toString();
    } else {
      return '$dartException\n$stack';
    }
  }

  /**
   * This method is installed as JavaScript toString method on
   * [DartError].  So JavaScript 'this' binds to an instance of
   * DartError.
   */
  static toStringWrapper() => JS('', r'this').toString();
}

makeLiteralListConst(list) {
  JS('bool', r'#.immutable$list = #', list, true);
  JS('bool', r'#.fixed$length = #', list, true);
  return list;
}

throwRuntimeError(message) {
  throw new RuntimeError(message);
}

/**
 * The SSA builder generates a call to this method when a malformed type is used
 * in a subtype test.
 */
throwMalformedSubtypeError(value, type, reasons) {
  throw new TypeErrorImplementation.malformedSubtype(value, type, reasons);
}

throwAbstractClassInstantiationError(className) {
  throw new AbstractClassInstantiationError(className);
}

/**
 * Called from catch blocks in generated code to extract the Dart
 * exception from the thrown value. The thrown value may have been
 * created by [$throw] or it may be a 'native' JS exception.
 *
 * Some native exceptions are mapped to new Dart instances, others are
 * returned unmodified.
 */
unwrapException(ex) {
  // Note that we are checking if the object has the property. If it
  // has, it could be set to null if the thrown value is null.
  if (JS('bool', r'"dartException" in #', ex)) {
    return JS('', r'#.dartException', ex);
  }

  // Grab hold of the exception message. This field is available on
  // all supported browsers.
  var message = JS('var', r'#.message', ex);

  if (JS('bool', r'# instanceof TypeError', ex)) {
    // The type and arguments fields are Chrome specific but they
    // allow us to get very detailed information about what kind of
    // exception occurred.
    var type = JS('var', r'#.type', ex);
    var name = JS('var', r'#.arguments ? #.arguments[0] : ""', ex, ex);
    if (contains(message, 'JSNull') ||
        type == 'property_not_function' ||
        type == 'called_non_callable' ||
        type == 'non_object_property_call' ||
        type == 'non_object_property_load') {
      return new NoSuchMethodError(null, name, [], {});
    } else if (type == 'undefined_method') {
      return new NoSuchMethodError('', name, [], {});
    }

    var ieErrorCode = JS('int', '#.number & 0xffff', ex);
    var ieFacilityNumber = JS('int', '#.number>>16 & 0x1FFF', ex);
    // If we cannot use [type] to determine what kind of exception
    // we're dealing with we fall back on looking at the exception
    // message if it is available and a string.
    if (message is String) {
      if (message == 'null has no properties' ||
          message == "'null' is not an object" ||
          message == "'undefined' is not an object" ||
          message.endsWith('is null') ||
          message.endsWith('is undefined') ||
          message.endsWith('is null or undefined') ||
          message.endsWith('of undefined') ||
          message.endsWith('of null')) {
        return new NoSuchMethodError(null, '<unknown>', [], {});
      } else if (contains(message, ' has no method ') ||
                 contains(message, ' is not a function') ||
                 (ieErrorCode == 438 && ieFacilityNumber == 10)) {
        // Examples:
        //  x.foo is not a function
        //  'undefined' is not a function (evaluating 'x.foo(1,2,3)')
        // Object doesn't support property or method 'foo' which sets the error
        // code 438 in IE.
        // TODO(kasperl): Compute the right name if possible.
        return new NoSuchMethodError('', '<unknown>', [], {});
      }
    }

    // If we cannot determine what kind of error this is, we fall back
    // to reporting this as a generic exception. It's probably better
    // than nothing.
    return new Exception(message is String ? message : '');
  }

  if (JS('bool', r'# instanceof RangeError', ex)) {
    if (message is String && contains(message, 'call stack')) {
      return new StackOverflowError();
    }

    // In general, a RangeError is thrown when trying to pass a number
    // as an argument to a function that does not allow a range that
    // includes that number.
    return new ArgumentError();
  }

  // Check for the Firefox specific stack overflow signal.
  if (JS('bool',
         r'typeof InternalError == "function" && # instanceof InternalError',
         ex)) {
    if (message is String && message == 'too much recursion') {
      return new StackOverflowError();
    }
  }

  // Just return the exception. We should not wrap it because in case
  // the exception comes from the DOM, it is a JavaScript
  // object backed by a native Dart class.
  return ex;
}

/**
 * Called by generated code to fetch the stack trace from an
 * exception.
 */
StackTrace getTraceFromException(exception) {
  return new StackTrace(JS("var", r"#.stack", exception));
}

class StackTrace {
  var stack;
  StackTrace(this.stack);
  String toString() => stack != null ? stack : '';
}


/**
 * Called by generated code to build a map literal. [keyValuePairs] is
 * a list of key, value, key, value, ..., etc.
 */
makeLiteralMap(List keyValuePairs) {
  Iterator iterator = keyValuePairs.iterator;
  Map result = new LinkedHashMap();
  while (iterator.moveNext()) {
    String key = iterator.current;
    iterator.moveNext();
    var value = iterator.current;
    result[key] = value;
  }
  return result;
}

invokeClosure(Function closure,
              var isolate,
              int numberOfArguments,
              var arg1,
              var arg2) {
  if (numberOfArguments == 0) {
    return JS_CALL_IN_ISOLATE(isolate, () => closure());
  } else if (numberOfArguments == 1) {
    return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1));
  } else if (numberOfArguments == 2) {
    return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2));
  } else {
    throw new Exception(
        'Unsupported number of arguments for wrapped closure');
  }
}

/**
 * Called by generated code to convert a Dart closure to a JS
 * closure when the Dart closure is passed to the DOM.
 */
convertDartClosureToJS(closure, int arity) {
  if (closure == null) return null;
  var function = JS('var', r'#.$identity', closure);
  if (JS('bool', r'!!#', function)) return function;

  // We use $0 and $1 to not clash with variable names used by the
  // compiler and/or minifier.
  function = JS('var',
                r'(function ($2, $3) {'
                    r' return function($0, $1) { '
                        r'return $3(#, $2, #, $0, $1) }})(#, #)',
                closure,
                arity,
                // Capture the current isolate now.  Remember that "#"
                // in JS is simply textual substitution of compiled
                // expressions.
                JS_CURRENT_ISOLATE(),
                DART_CLOSURE_TO_JS(invokeClosure));

  JS('void', r'#.$identity = #', closure, function);
  return function;
}

/**
 * Super class for Dart closures.
 */
class Closure implements Function {
  String toString() => "Closure";
}

bool jsHasOwnProperty(var jsObject, String property) {
  return JS('bool', r'#.hasOwnProperty(#)', jsObject, property);
}

jsPropertyAccess(var jsObject, String property) {
  return JS('var', r'#[#]', jsObject, property);
}

/**
 * Called at the end of unaborted switch cases to get the singleton
 * FallThroughError exception that will be thrown.
 */
getFallThroughError() => const FallThroughErrorImplementation();

/**
 * Represents the type Dynamic. The compiler treats this specially.
 */
abstract class Dynamic_ {
}

/**
 * A metadata annotation describing the types instantiated by a native element.
 *
 * The annotation is valid on a native method and a field of a native class.
 *
 * By default, a field of a native class is seen as an instantiation point for
 * all native classes that are a subtype of the field's type, and a native
 * method is seen as an instantiation point fo all native classes that are a
 * subtype of the method's return type, or the argument types of the declared
 * type of the method's callback parameter.
 *
 * An @[Creates] annotation overrides the default set of instantiated types.  If
 * one or more @[Creates] annotations are present, the type of the native
 * element is ignored, and the union of @[Creates] annotations is used instead.
 * The names in the strings are resolved and the program will fail to compile
 * with dart2js if they do not name types.
 *
 * The argument to [Creates] is a string.  The string is parsed as the names of
 * one or more types, separated by vertical bars `|`.  There are some special
 * names:
 *
 * * `=List`. This means 'exactly List', which is the JavaScript Array
 *   implementation of [List] and no other implementation.
 *
 * * `=Object`. This means 'exactly Object', which is a plain JavaScript object
 *   with properties and none of the subtypes of Object.
 *
 * Example: we may know that a method always returns a specific implementation:
 *
 *     @Creates('_NodeList')
 *     List<Node> getElementsByTagName(String tag) native;
 *
 * Useful trick: A method can be marked as not instantiating any native classes
 * with the annotation `@Creates('Null')`.  This is useful for fields on native
 * classes that are used only in Dart code.
 *
 *     @Creates('Null')
 *     var _cachedFoo;
 */
class Creates {
  final String types;
  const Creates(this.types);
}

/**
 * A metadata annotation describing the types returned or yielded by a native
 * element.
 *
 * The annotation is valid on a native method and a field of a native class.
 *
 * By default, a native method or field is seen as returning or yielding all
 * subtypes if the method return type or field type.  This annotation allows a
 * more precise set of types to be specified.
 *
 * See [Creates] for the syntax of the argument.
 *
 * Example: IndexedDB keys are numbers, strings and JavaScript Arrays of keys.
 *
 *     @Returns('String|num|=List')
 *     dynamic key;
 *
 *     // Equivalent:
 *     @Returns('String') @Returns('num') @Returns('=List')
 *     dynamic key;
 */
class Returns {
  final String types;
  const Returns(this.types);
}

/**
 * A metadata annotation placed on native methods and fields of native classes
 * to specify the JavaScript name.
 *
 * This example declares a Dart field + getter + setter called `$dom_title` that
 * corresponds to the JavaScript property `title`.
 *
 *     class Docmument native "*Foo" {
 *       @JSName('title')
 *       String $dom_title;
 *     }
 */
class JSName {
  final String name;
  const JSName(this.name);
}

/**
 * Represents the type of Null. The compiler treats this specially.
 * TODO(lrn): Null should be defined in core. It's a class, like int.
 * It just happens to act differently in assignability tests and,
 * like int, can't be extended or implemented.
 */
class Null {
  factory Null() {
    throw new UnsupportedError('new Null()');
  }
}

setRuntimeTypeInfo(target, typeInfo) {
  assert(typeInfo == null || isJsArray(typeInfo));
  // We have to check for null because factories may return null.
  if (target != null) JS('var', r'#.$builtinTypeInfo = #', target, typeInfo);
}

getRuntimeTypeInfo(target) {
  if (target == null) return null;
  return JS('var', r'#.$builtinTypeInfo', target);
}

getRuntimeTypeArgument(target, substitution, index) {
  var arguments = substitute(substitution, getRuntimeTypeInfo(target));
  return (arguments == null) ? null : getField(arguments, index);
}

/**
 * The following methods are called by the runtime to implement
 * checked mode and casts. We specialize each primitive type (eg int, bool), and
 * use the compiler's convention to do is-checks on regular objects.
 */
boolConversionCheck(value) {
  boolTypeCheck(value);
  assert(value != null);
  return value;
}

stringTypeCheck(value) {
  if (value == null) return value;
  if (value is String) return value;
  throw new TypeErrorImplementation(value, 'String');
}

stringTypeCast(value) {
  if (value is String || value == null) return value;
  // TODO(lrn): When reified types are available, pass value.class and String.
  throw new CastErrorImplementation(
      Primitives.objectTypeName(value), 'String');
}

doubleTypeCheck(value) {
  if (value == null) return value;
  if (value is double) return value;
  throw new TypeErrorImplementation(value, 'double');
}

doubleTypeCast(value) {
  if (value is double || value == null) return value;
  throw new CastErrorImplementation(
      Primitives.objectTypeName(value), 'double');
}

numTypeCheck(value) {
  if (value == null) return value;
  if (value is num) return value;
  throw new TypeErrorImplementation(value, 'num');
}

numTypeCast(value) {
  if (value is num || value == null) return value;
  throw new CastErrorImplementation(
      Primitives.objectTypeName(value), 'num');
}

boolTypeCheck(value) {
  if (value == null) return value;
  if (value is bool) return value;
  throw new TypeErrorImplementation(value, 'bool');
}

boolTypeCast(value) {
  if (value is bool || value == null) return value;
  throw new CastErrorImplementation(
      Primitives.objectTypeName(value), 'bool');
}

functionTypeCheck(value) {
  if (value == null) return value;
  if (value is Function) return value;
  throw new TypeErrorImplementation(value, 'Function');
}

functionTypeCast(value) {
  if (value is Function || value == null) return value;
  throw new CastErrorImplementation(
      Primitives.objectTypeName(value), 'Function');
}

intTypeCheck(value) {
  if (value == null) return value;
  if (value is int) return value;
  throw new TypeErrorImplementation(value, 'int');
}

intTypeCast(value) {
  if (value is int || value == null) return value;
  throw new CastErrorImplementation(
      Primitives.objectTypeName(value), 'int');
}

void propertyTypeError(value, property) {
  // Cuts the property name to the class name.
  String name = property.substring(3, property.length);
  throw new TypeErrorImplementation(value, name);
}

void propertyTypeCastError(value, property) {
  // Cuts the property name to the class name.
  String actualType = Primitives.objectTypeName(value);
  String expectedType = property.substring(3, property.length);
  throw new CastErrorImplementation(actualType, expectedType);
}

/**
 * For types that are not supertypes of native (eg DOM) types,
 * we emit a simple property check to check that an object implements
 * that type.
 */
propertyTypeCheck(value, property) {
  if (value == null) return value;
  if (JS('bool', '!!#[#]', value, property)) return value;
  propertyTypeError(value, property);
}

/**
 * For types that are not supertypes of native (eg DOM) types,
 * we emit a simple property check to check that an object implements
 * that type.
 */
propertyTypeCast(value, property) {
  if (value == null || JS('bool', '!!#[#]', value, property)) return value;
  propertyTypeCastError(value, property);
}

/**
 * For types that are supertypes of native (eg DOM) types, we emit a
 * call because we cannot add a JS property to their prototype at load
 * time.
 */
callTypeCheck(value, property) {
  if (value == null) return value;
  if ((identical(JS('String', 'typeof #', value), 'object'))
      && JS('bool', '#[#]()', value, property)) {
    return value;
  }
  propertyTypeError(value, property);
}

/**
 * For types that are supertypes of native (eg DOM) types, we emit a
 * call because we cannot add a JS property to their prototype at load
 * time.
 */
callTypeCast(value, property) {
  if (value == null
      || ((JS('bool', 'typeof # === "object"', value))
          && JS('bool', '#[#]()', value, property))) {
    return value;
  }
  propertyTypeCastError(value, property);
}

/**
 * Specialization of the type check for num and String and their
 * supertype since [value] can be a JS primitive.
 */
numberOrStringSuperTypeCheck(value, property) {
  if (value == null) return value;
  if (value is String) return value;
  if (value is num) return value;
  if (JS('bool', '!!#[#]', value, property)) return value;
  propertyTypeError(value, property);
}

numberOrStringSuperTypeCast(value, property) {
  if (value is String) return value;
  if (value is num) return value;
  return propertyTypeCast(value, property);
}

numberOrStringSuperNativeTypeCheck(value, property) {
  if (value == null) return value;
  if (value is String) return value;
  if (value is num) return value;
  if (JS('bool', '#[#]()', value, property)) return value;
  propertyTypeError(value, property);
}

numberOrStringSuperNativeTypeCast(value, property) {
  if (value == null) return value;
  if (value is String) return value;
  if (value is num) return value;
  if (JS('bool', '#[#]()', value, property)) return value;
  propertyTypeCastError(value, property);
}

/**
 * Specialization of the type check for String and its supertype
 * since [value] can be a JS primitive.
 */
stringSuperTypeCheck(value, property) {
  if (value == null) return value;
  if (value is String) return value;
  if (JS('bool', '!!#[#]', value, property)) return value;
  propertyTypeError(value, property);
}

stringSuperTypeCast(value, property) {
  if (value is String) return value;
  return propertyTypeCast(value, property);
}

stringSuperNativeTypeCheck(value, property) {
  if (value == null) return value;
  if (value is String) return value;
  if (JS('bool', '#[#]()', value, property)) return value;
  propertyTypeError(value, property);
}

stringSuperNativeTypeCast(value, property) {
  if (value is String || value == null) return value;
  if (JS('bool', '#[#]()', value, property)) return value;
  propertyTypeCastError(value, property);
}

/**
 * Specialization of the type check for List and its supertypes,
 * since [value] can be a JS array.
 */
listTypeCheck(value) {
  if (value == null) return value;
  if (value is List) return value;
  throw new TypeErrorImplementation(value, 'List');
}

listTypeCast(value) {
  if (value is List || value == null) return value;
  throw new CastErrorImplementation(
      Primitives.objectTypeName(value), 'List');
}

listSuperTypeCheck(value, property) {
  if (value == null) return value;
  if (value is List) return value;
  if (JS('bool', '!!#[#]', value, property)) return value;
  propertyTypeError(value, property);
}

listSuperTypeCast(value, property) {
  if (value is List) return value;
  return propertyTypeCast(value, property);
}

listSuperNativeTypeCheck(value, property) {
  if (value == null) return value;
  if (value is List) return value;
  if (JS('bool', '#[#]()', value, property)) return value;
  propertyTypeError(value, property);
}

listSuperNativeTypeCast(value, property) {
  if (value is List || value == null) return value;
  if (JS('bool', '#[#]()', value, property)) return value;
  propertyTypeCastError(value, property);
}

voidTypeCheck(value) {
  if (value == null) return value;
  throw new TypeErrorImplementation(value, 'void');
}

malformedTypeCheck(value, type, reasons) {
  if (value == null) return value;
  throwMalformedSubtypeError(value, type, reasons);
}

malformedTypeCast(value, type, reasons) {
  if (value == null) return value;
  throw new CastErrorImplementation.malformedTypeCast(value, type, reasons);
}

/**
 * Special interface recognized by the compiler and implemented by DOM
 * objects that support integer indexing. This interface is not
 * visible to anyone, and is only injected into special libraries.
 */
abstract class JavaScriptIndexingBehavior {
}

// TODO(lrn): These exceptions should be implemented in core.
// When they are, remove the 'Implementation' here.

/** Thrown by type assertions that fail. */
class TypeErrorImplementation implements TypeError {
  final String message;

  /**
   * Normal type error caused by a failed subtype test.
   */
  TypeErrorImplementation(Object value, String type)
      : message = "type '${Primitives.objectTypeName(value)}' is not a subtype "
                  "of type '$type'";

  /**
   * Type error caused by a subtype test on a malformed type.
   */
  TypeErrorImplementation.malformedSubtype(Object value,
                                           String type, String reasons)
      : message = "type '${Primitives.objectTypeName(value)}' is not a subtype "
                  "of type '$type' because '$type' is malformed: $reasons.";

  String toString() => message;
}

/** Thrown by the 'as' operator if the cast isn't valid. */
class CastErrorImplementation implements CastError {
  // TODO(lrn): Rename to CastError (and move implementation into core).
  final String message;

  /**
   * Normal cast error caused by a failed type cast.
   */
  CastErrorImplementation(Object actualType, Object expectedType)
      : message = "CastError: Casting value of type $actualType to"
                  " incompatible type $expectedType";


  /**
   * Cast error caused by a type cast to a malformed type.
   */
  CastErrorImplementation.malformedTypeCast(Object value,
                                            String type, String reasons)
      : message = "CastError: Type '${Primitives.objectTypeName(value)}' "
                  "cannot be cast to type '$type' because '$type' is "
                  "malformed: $reasons.";


  String toString() => message;
}

class FallThroughErrorImplementation implements FallThroughError {
  const FallThroughErrorImplementation();
  String toString() => "Switch case fall-through.";
}

/**
 * Helper function for implementing asserts. The compiler treats this specially.
 */
void assertHelper(condition) {
  if (condition is Function) condition = condition();
  if (condition is !bool) {
    throw new TypeErrorImplementation(condition, 'bool');
  }
  // Compare to true to avoid boolean conversion check in checked
  // mode.
  if (!identical(condition, true)) throw new AssertionError();
}

/**
 * Called by generated code when a method that must be statically
 * resolved cannot be found.
 */
void throwNoSuchMethod(obj, name, arguments, expectedArgumentNames) {
  throw new NoSuchMethodError(obj, name, arguments, const {},
                              expectedArgumentNames);
}

/**
 * Called by generated code when a static field's initializer references the
 * field that is currently being initialized.
 */
void throwCyclicInit(String staticName) {
  throw new RuntimeError("Cyclic initialization for static $staticName");
}

class TypeImpl implements Type {
  final String typeName;
  TypeImpl(this.typeName);
  toString() => typeName;
  int get hashCode => typeName.hashCode;
  bool operator ==(other) {
    if (other is !TypeImpl) return false;
    return typeName == other.typeName;
  }
}

String getClassName(var object) {
  return JS('String', r'#.constructor.builtin$cls', object);
}

String getRuntimeTypeAsString(List runtimeType) {
  String className = getConstructorName(runtimeType[0]);
  if (runtimeType.length == 1) return className;
  return '$className<${joinArguments(runtimeType, 1)}>';
}

String getConstructorName(type) => JS('String', r'#.builtin$cls', type);

String runtimeTypeToString(type) {
  if (type == null) {
    return 'dynamic';
  } else if (isJsArray(type)) {
    // A list representing a type with arguments.
    return getRuntimeTypeAsString(type);
  } else {
    // A reference to the constructor.
    return getConstructorName(type);
  }
}

String joinArguments(var types, int startIndex) {
  bool firstArgument = true;
  StringBuffer buffer = new StringBuffer();
  for (int index = startIndex; index < types.length; index++) {
    if (firstArgument) {
      firstArgument = false;
    } else {
      buffer. add(', ');
    }
    var argument = types[index];
    buffer.add(runtimeTypeToString(argument));
  }
  return buffer.toString();
}

String getRuntimeTypeString(var object) {
  String className = isJsArray(object) ? 'List' : getClassName(object);
  var typeInfo = JS('var', r'#.$builtinTypeInfo', object);
  if (typeInfo == null) return className;
  return "$className<${joinArguments(typeInfo, 0)}>";
}

bool isJsFunction(var o) => JS('bool', r'typeof # == "function"', o);

Object invoke(function, arguments) {
  return JS('var', r'#.apply(null, #)', function, arguments);
}

substitute(var substitution, var arguments) {
  if (isJsArray(substitution)) {
    arguments = substitution;
  } else if (isJsFunction(substitution)) {
    arguments = invoke(substitution, arguments);
  }
  return arguments;
}

/**
 * Check that the types in the list [arguments] are subtypes of the types in
 * list [checks] (at the respective positions), possibly applying [substitution]
 * to the arguments before the check.
 *
 * See [:RuntimeTypes.getSubtypeSubstitution:] for a description of the possible
 * values for [substitution].
 */
bool checkArguments(var substitution, var arguments, var checks) {
  return areSubtypes(substitute(substitution, arguments), checks);
}

bool areSubtypes(List s, List t) {
  // [:null:] means a raw type.
  if (s == null || t == null) return true;

  assert(isJsArray(s));
  assert(isJsArray(t));
  assert(s.length == t.length);

  int len = s.length;
  for (int i = 0; i < len; i++) {
    if (!isSubtype(s[i], t[i])) {
      return false;
    }
  }
  return true;
}

getArguments(var type) {
  return isJsArray(type) ? JS('var', r'#.slice(1)', type) : null;
}

getField(var object, var name) => JS('var', r'#[#]', object, name);

/**
 * Tests whether the Dart object [o] is a subtype of the runtime type
 * representation [t], which is a type representation as described in the
 * comment on [isSubtype].
 */
bool objectIsSubtype(Object o, var t) {
  if (JS('bool', '# == null', o) || JS('bool', '# == null', t)) return true;
  // Get the runtime type information from the object here, because we may
  // overwrite o with the interceptor below.
  var rti = getRuntimeTypeInfo(o);
  // Check for native objects and use the interceptor instead of the object.
  o = getInterceptor(o);
  // We can use the object as its own type representation because we install
  // the subtype flags and the substitution on the prototype, so they are
  // properties of the object in JS.
  var type;
  if (JS('bool', '# != null', rti)) {
    // If the type has type variables (that is, [:rti != null:]), make a copy of
    // the type arguments and insert [o] in the first position to create a
    // compound type representation.
    type = JS('List', '#.slice()', rti);
    JS('', '#.splice(0, 0, #)', type, o);
  } else {
    // Use the object as representation of the raw type.
    type = o;
  }
  return isSubtype(type, t);
}


/**
 * Check whether the type represented by [s] is a subtype of the type
 * represented by [t].
 *
 * Type representations can be:
 *  1) a JavaScript constructor for a class C: the represented type is the raw
 *     type C.
 *  2) a Dart object: this is the interceptor instance for a native type.
 *  3) a JavaScript object: this represents a class for which there is no
 *     JavaScript constructor, because it is only used in type arguments or it
 *     is native. The represented type is the raw type of this class.
 *  4) a JavaScript array: the first entry is of type 1, 2 or 3 and contains the
 *     subtyping flags and the substitution of the type and the rest of the
 *     array are the type arguments.
 *  5) [:null:]: the dynamic type.
 */
bool isSubtype(var s, var t) {
  // If either type is dynamic, [s] is a subtype of [t].
  if (JS('bool', '# == null', s) || JS('bool', '# == null', t)) return true;
  // Subtyping is reflexive.
  if (JS('bool', '# === #', s, t)) return true;
  // Get the object describing the class and check for the subtyping flag
  // constructed from the type of [t].
  var typeOfS = isJsArray(s) ? s[0] : s;
  var typeOfT = isJsArray(t) ? t[0] : t;
  // Check for a subtyping flag.
  var test = '${JS_OPERATOR_IS_PREFIX()}${runtimeTypeToString(typeOfT)}';
  if (getField(typeOfS, test) == null) return false;
  // Get the necessary substitution of the type arguments, if there is one.
  var substitution;
  if (JS('bool', '# !== #', typeOfT, typeOfS)) {
    var field = '${JS_OPERATOR_AS_PREFIX()}${runtimeTypeToString(typeOfT)}';
    substitution = getField(typeOfS, field);
  }
  // The class of [s] is a subclass of the class of [t].  If [s] has no type
  // arguments and no substitution, it is used as raw type.  If [t] has no
  // type arguments, it used as a raw type.  In both cases, [s] is a subtype
  // of [t].
  if ((!isJsArray(s) && JS('bool', '# == null', substitution)) ||
      !isJsArray(t)) {
    return true;
  }
  // Recursively check the type arguments.
  return checkArguments(substitution, getArguments(s), getArguments(t));
}

createRuntimeType(String name) => new TypeImpl(name);
