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

/// This library defines the representation of runtime types.
part of dart._runtime;

/// Returns the state of [flag] that is determined at compile time.
///
/// The constant value itself is inlined by the compiler in place of the call
/// to this method.
@notNull
external bool compileTimeFlag(String flag);

_throwInvalidFlagError(String message) =>
    throw UnsupportedError('Invalid flag combination.\n$message');

@notNull
bool _weakNullSafetyWarnings = false;

/// Sets the runtime mode to show warnings when types violate sound null safety.
///
/// This option is not compatible with weak null safety errors or sound null
/// safety (the warnings will be errors).
void weakNullSafetyWarnings(bool showWarnings) {
  if (showWarnings && compileTimeFlag('soundNullSafety')) {
    _throwInvalidFlagError(
        'Null safety violations cannot be shown as warnings when running with '
        'sound null safety.');
  }

  _weakNullSafetyWarnings = showWarnings;
}

@notNull
bool _weakNullSafetyErrors = false;

/// Sets the runtime mode to throw errors when types violate sound null safety.
///
/// This option is not compatible with weak null safety warnings (the warnings
/// are now errors) or sound null safety (the errors are already errors).
void weakNullSafetyErrors(bool showErrors) {
  if (showErrors && compileTimeFlag('soundNullSafety')) {
    _throwInvalidFlagError(
        'Null safety violations are already thrown as errors when running with '
        'sound null safety.');
  }

  if (showErrors && _weakNullSafetyWarnings) {
    _throwInvalidFlagError(
        'Null safety violations can be shown as warnings or thrown as errors, '
        'not both.');
  }

  _weakNullSafetyErrors = showErrors;
}

@notNull
bool _nonNullAsserts = false;

/// Sets the runtime mode to insert non-null assertions on non-nullable method
/// parameters.
///
/// When [weakNullSafetyWarnings] is also `true` the assertions will fail
/// instead of printing a warning for the non-null parameters.
void nonNullAsserts(bool enable) {
  _nonNullAsserts = enable;
}

@notNull
bool _nativeNonNullAsserts = false;

/// Enables null assertions on native APIs to make sure value returned from the
/// browser is sound.
///
/// These apply to dart:html and similar web libraries. Note that these only are
/// added in sound null-safety only.
void nativeNonNullAsserts(bool enable) {
  _nativeNonNullAsserts = enable;
}

final metadata = JS('', 'Symbol("metadata")');

/// A javascript Symbol used to store a canonical version of T? on T.
final _cachedNullable = JS('', 'Symbol("cachedNullable")');

/// A javascript Symbol used to store a canonical version of T* on T.
final _cachedLegacy = JS('', 'Symbol("cachedLegacy")');

/// A javascript Symbol used to store prior subtype checks and their results.
final _subtypeCache = JS('', 'Symbol("_subtypeCache")');

/// Types in dart are represented internally at runtime as follows.
///
///   - Normal nominal types, produced from classes, are represented
///     at runtime by the JS class of which they are an instance.
///     If the type is the result of instantiating a generic class,
///     then the "classes" module manages the association between the
///     instantiated class and the original class declaration
///     and the type arguments with which it was instantiated.  This
///     association can be queried via the "classes" module".
///
///   - All other types are represented as instances of class [DartType],
///     defined in this module.
///     - Dynamic, Void, and Bottom are singleton instances of sentinel
///       classes.
///     - Function types are instances of subclasses of AbstractFunctionType.
///
/// Function types are represented in one of two ways:
///   - As an instance of FunctionType.  These are eagerly computed.
///   - As an instance of TypeDef.  The TypeDef representation lazily
///     computes an instance of FunctionType, and delegates to that instance.
///
/// These above "runtime types" are what is used for implementing DDC's
/// internal type checks. These objects are distinct from the objects exposed
/// to user code by class literals and calling `Object.runtimeType`. In DDC,
/// the latter are represented by instances of WrappedType which contain a
/// real runtime type internally. This ensures that the returned object only
/// exposes the API that Type defines:
///
///     get String name;
///     String toString();
///
/// These "runtime types" have methods for performing type checks. The methods
/// have the following JavaScript names which are designed to not collide with
/// static methods, which are also placed 'on' the class constructor function.
///
///     T.is(o): Implements 'o is T'.
///     T.as(o): Implements 'o as T'.
///
/// By convention, we used named JavaScript functions for these methods with the
/// name 'is_X' and 'as_X' for various X to indicate the type or the
/// implementation strategy for the test (e.g 'is_String', 'is_G' for generic
/// types, etc.)
// TODO(jmesserly): we shouldn't implement Type here. It should be moved down
// to AbstractFunctionType.
class DartType implements Type {
  String get name => this.toString();

  // TODO(jmesserly): these should never be reached, can be make them abstract?
  @notNull
  @JSExportName('is')
  bool is_T(object) => instanceOf(object, this);

  @JSExportName('as')
  as_T(object) => cast(object, this);

  DartType() {
    // Every instance of a DartType requires a set of type caches.
    JS('', '#(this)', addTypeCaches);
  }
}

class DynamicType extends DartType {
  toString() => 'dynamic';

  @notNull
  @JSExportName('is')
  bool is_T(object) => true;

  @JSExportName('as')
  Object? as_T(Object? object) => object;
}

@notNull
bool _isJsObject(obj) =>
    JS('!', '# === #', getReifiedType(obj), typeRep<LegacyJavaScriptObject>());

/// Asserts that [f] is a native JS functions and returns it if so.
///
/// This function should be used to ensure that a function is a native JS
/// function before it is passed to native JS code.
@NoReifyGeneric()
F assertInterop<F extends Function?>(F f) {
  assert(
      _isJsObject(f) ||
          !JS<bool>('bool', '# instanceof #.Function', f, global_),
      'Dart function requires `allowInterop` to be passed to JavaScript.');
  return f;
}

bool isDartFunction(obj) =>
    JS<bool>('!', '# instanceof Function', obj) &&
    JS<bool>('!', '#[#] != null', obj, _runtimeType);

Expando<Function> _assertInteropExpando = Expando<Function>();

@NoReifyGeneric()
F tearoffInterop<F extends Function?>(F f) {
  // Wrap a JS function with a closure that ensures all function arguments are
  // native JS functions.
  if (!_isJsObject(f) || f == null) return f;
  var ret = _assertInteropExpando[f];
  if (ret == null) {
    ret = JS(
        '',
        'function (...arguments) {'
            ' var args = arguments.map(#);'
            ' return #.apply(this, args);'
            '}',
        assertInterop,
        f);
    _assertInteropExpando[f] = ret;
  }
  // Suppress a cast back to F.
  return JS('', '#', ret);
}

/// Dart type that represents a package:js class type (either anonymous or not).
///
/// For the purposes of subtype checks, these match any JS type.
class PackageJSType extends DartType {
  final String _dartName;
  PackageJSType(this._dartName);

  @override
  String toString() => _dartName;

  @notNull
  @JSExportName('is')
  bool is_T(obj) =>
      obj != null &&
      (_isJsObject(obj) || isSubtypeOf(getReifiedType(obj), this));

  @JSExportName('as')
  as_T(obj) => is_T(obj) ? obj : castError(obj, this);
}

void _warn(arg) {
  JS('void', 'console.warn(#)', arg);
}

void _nullWarn(message) {
  if (_weakNullSafetyWarnings) {
    _warn('$message\n'
        'This will become a failure when runtime null safety is enabled.');
  } else if (_weakNullSafetyErrors) {
    throw TypeErrorImpl(message);
  }
}

/// Tracks objects that have been compared against null (i.e., null is Type).
/// Separating this null set out from _cacheMaps lets us fast-track common
/// legacy type checks.
/// TODO: Delete this set when legacy nullability is phased out.
var _nullComparisonSet = JS<Object>('', 'new Set()');

/// Warn on null cast failures when casting to a particular non-nullable
/// `type`.  Note, we cache by type to avoid excessive warning messages at
/// runtime.
/// TODO(vsm): Consider changing all invocations to pass / cache on location
/// instead.  That gives more useful feedback to the user.
void _nullWarnOnType(type) {
  bool result = JS('', '#.has(#)', _nullComparisonSet, type);
  if (!result) {
    JS('', '#.add(#)', _nullComparisonSet, type);
    _nullWarn("Null is not a subtype of $type.");
  }
}

var _packageJSTypes = JS<Object>('', 'new Map()');

packageJSType(String name) {
  var ret = JS('', '#.get(#)', _packageJSTypes, name);
  if (ret == null) {
    ret = PackageJSType(name);
    JS('', '#.set(#, #)', _packageJSTypes, name, ret);
  }
  return ret;
}

/// Since package:js types are all subtypes of each other, we use this var to
/// denote *some* package:js type in our subtyping logic.
///
/// Used only when a concrete PackageJSType is not available i.e. when neither
/// the object nor the target type is a PackageJSType. Avoids initializating a
/// new PackageJSType every time. Note that we don't add it to the set of JS
/// types, since it's not an actual JS class.
final _pkgJSTypeForSubtyping = PackageJSType('');

/// Returns a nullable (question, ?) version of [type].
///
/// The resulting type returned in a normalized form based on the rules from the
/// normalization doc:
/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
@notNull
Object nullable(@notNull Object type) {
  // Check if a nullable version of this type has already been created.
  var cached = JS<Object>('', '#[#]', type, _cachedNullable);
  if (JS<bool>('!', '# !== void 0', cached)) {
    return cached;
  }

  // Cache a canonical nullable version of this type on this type.
  Object cachedType = _computeNullable(type);
  JS('', '#[#] = #', type, _cachedNullable, cachedType);
  return cachedType;
}

Object _computeNullable(@notNull Object type) {
  // *? normalizes to ?.
  if (_jsInstanceOf(type, LegacyType)) {
    return nullable(JS<Object>('!', '#.type', type));
  }
  if (_jsInstanceOf(type, NullableType) ||
      _isTop(type) ||
      _equalType(type, Null) ||
      // Normalize FutureOr<T?>? --> FutureOr<T?>
      // All other runtime FutureOr normalization is in `normalizeFutureOr()`.
      ((_isFutureOr(type)) &&
          _jsInstanceOf(
              JS<Object>('!', '#[0]', getGenericArgs(type)), NullableType))) {
    return type;
  }
  if (_equalType(type, Never)) return unwrapType(Null);
  return NullableType(JS<Type>('!', '#', type));
}

/// Returns a legacy (star, *) version of [type].
///
/// The resulting type returned in a normalized form based on the rules from the
/// normalization doc:
/// https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
@notNull
Object legacy(@notNull Object type) {
  // Check if a legacy version of this type has already been created.
  var cached = JS<Object>('', '#[#]', type, _cachedLegacy);
  if (JS<bool>('!', '# !== void 0', cached)) {
    return cached;
  }

  // Cache a canonical legacy version of this type on this type.
  Object cachedType = _computeLegacy(type);
  JS('', '#[#] = #', type, _cachedLegacy, cachedType);
  return cachedType;
}

Object _computeLegacy(@notNull Object type) {
  // Note: ?* normalizes to ?, so we cache type? at type?[_cachedLegacy].
  if (_jsInstanceOf(type, LegacyType) ||
      _jsInstanceOf(type, NullableType) ||
      _isTop(type) ||
      _equalType(type, Null)) {
    return type;
  }
  return LegacyType(JS<Type>('!', '#', type));
}

/// A wrapper to identify a nullable (question, ?) type of the form [type]?.
class NullableType extends DartType {
  final Type type;

  NullableType(@notNull this.type);

  @override
  String get name => _jsInstanceOf(type, FunctionType) ? '($type)?' : '$type?';

  @override
  String toString() => name;

  @JSExportName('is')
  bool is_T(obj) => obj == null || JS<bool>('!', '#.is(#)', type, obj);

  @JSExportName('as')
  as_T(obj) => obj == null || JS<bool>('!', '#.is(#)', type, obj)
      ? obj
      : cast(obj, this);
}

/// A wrapper to identify a legacy (star, *) type of the form [type]*.
class LegacyType extends DartType {
  final Type type;

  LegacyType(@notNull this.type);

  @override
  String get name => '$type';

  @override
  String toString() => name;

  @JSExportName('is')
  bool is_T(obj) {
    if (obj == null) {
      // Object and Never are the only legacy types that should return true if
      // obj is `null`.
      return _equalType(type, Object) || _equalType(type, Never);
    }
    return JS<bool>('!', '#.is(#)', type, obj);
  }

  @JSExportName('as')
  as_T(obj) => obj == null || JS<bool>('!', '#.is(#)', type, obj)
      ? obj
      : cast(obj, this);
}

// TODO(nshahan) Add override optimizations for is and as?
class NeverType extends DartType {
  @override
  toString() => 'Never';
}

@JSExportName('Never')
final _never = NeverType();

@JSExportName('dynamic')
final _dynamic = DynamicType();

class VoidType extends DartType {
  toString() => 'void';

  @notNull
  @JSExportName('is')
  bool is_T(object) => true;

  @JSExportName('as')
  Object? as_T(Object? object) => object;
}

@JSExportName('void')
final void_ = VoidType();

// TODO(nshahan): Cleanup and consolidate NeverType, BottomType, bottom, _never.
class BottomType extends DartType {
  toString() => 'bottom';
}

final bottom = unwrapType(Null);

/// Dev Compiler's implementation of Type, wrapping its internal [_type].
class _Type extends Type {
  /// The internal type representation, either a [DartType] or class constructor
  /// function.
  // TODO(jmesserly): introduce InterfaceType so we don't have to special case
  // classes
  @notNull
  final Object _type;

  _Type(this._type);

  toString() => typeName(_type);

  Type get runtimeType => Type;
}

/// Given an internal runtime type object [type], wraps it in a `_Type` object
/// that implements the dart:core Type interface.
///
/// [isNormalized] is true when [type] is known to be in a canonicalized
/// normal form, so the algorithm can directly wrap and return the value.
Type wrapType(type, [@notNull bool isNormalized = false]) {
  // If we've already wrapped this type once, use the previous wrapper. This
  // way, multiple references to the same type return an identical Type.
  if (JS('!', '#.hasOwnProperty(#)', type, _typeObject)) {
    return JS('', '#[#]', type, _typeObject);
  }
  var result = isNormalized
      ? _Type(type)
      : (_jsInstanceOf(type, LegacyType)
          ? wrapType(JS<Object>('!', '#.type', type))
          : _canonicalizeNormalizedTypeObject(type));
  JS('', '#[#] = #', type, _typeObject, result);
  return result;
}

/// Constructs a normalized version of a type.
///
/// Used for type object identity. Normalization requires us to return a
/// canonicalized version of the input with all legacy wrappers removed.
Type _canonicalizeNormalizedTypeObject(type) {
  assert(!_jsInstanceOf(type, LegacyType));
  // We don't call _canonicalizeNormalizedTypeObject recursively but call wrap
  // + unwrap to handle legacy types automatically and force caching the
  // canonicalized type under the _typeObject cache property directly. This
  // way we ensure we always use the canonical normalized instance for each
  // type term.
  Object normalizeHelper(a) => unwrapType(wrapType(a));

  // GenericFunctionTypeIdentifiers are implicitly normalized.
  if (_jsInstanceOf(type, GenericFunctionTypeIdentifier)) {
    return wrapType(type, true);
  }
  if (_jsInstanceOf(type, FunctionType)) {
    var normReturnType = normalizeHelper(type.returnType);
    var normArgs = type.args.map(normalizeHelper).toList();
    if (JS<bool>('!', '#.Object.keys(#).length === 0', global_, type.named) &&
        JS<bool>('!', '#.Object.keys(#).length === 0', global_,
            type.requiredNamed)) {
      if (type.optionals.isEmpty) {
        var normType = fnType(normReturnType, normArgs);
        return wrapType(normType, true);
      }
      var normOptionals = type.optionals.map(normalizeHelper).toList();
      var normType = fnType(normReturnType, normArgs, normOptionals);
      return wrapType(normType, true);
    }
    var normNamed = JS('', '{}');
    _transformJSObject(type.named, normNamed, normalizeHelper);
    var normRequiredNamed = JS('', '{}');
    _transformJSObject(type.requiredNamed, normRequiredNamed, normalizeHelper);
    var normType =
        fnType(normReturnType, normArgs, normNamed, normRequiredNamed);
    return wrapType(normType, true);
  }
  if (_jsInstanceOf(type, GenericFunctionType)) {
    var formals = _getCanonicalTypeFormals(type.typeFormals.length);
    List<dynamic> normBounds =
        type.instantiateTypeBounds(formals).map(normalizeHelper).toList();

    var substitutedTypes = [];
    if (normBounds.contains(_never)) {
      // Normalize type arguments that are bounded by Never to Never at their
      // use site in the function type signature.
      for (var i = 0; i < formals.length; i++) {
        var substitutedType = normBounds[i];
        while (formals.contains(substitutedType)) {
          substitutedType = normBounds[formals.indexOf(substitutedType)];
        }
        if (substitutedType == _never) {
          substitutedTypes.add(_never);
        } else {
          substitutedTypes.add(formals[i]);
        }
      }
    } else {
      substitutedTypes = formals;
    }

    var normFunc =
        normalizeHelper(type.instantiate(substitutedTypes)) as FunctionType;
    // Create a comparison key for structural identity.
    var typeObjectIdKey = JS('', '[]');
    JS('', '#.push(...#)', typeObjectIdKey, normBounds);
    JS('', '#.push(#)', typeObjectIdKey, normFunc);
    var memoizedId = _memoizeArray(_gFnTypeTypeMap, typeObjectIdKey,
        () => GenericFunctionTypeIdentifier(formals, normBounds, normFunc));
    return wrapType(memoizedId, true);
  }
  var args = getGenericArgs(type);
  var normType;
  if (args == null || args.isEmpty) {
    normType = type;
  } else {
    var genericClass = getGenericClass(type);
    var normArgs = args.map(normalizeHelper).toList();
    normType = JS('!', '#(...#)', genericClass, normArgs);
  }
  return wrapType(normType, true);
}

/// Generates new values by applying [transform] to the values of [srcObject],
/// storing them in [dstObject] with the same key.
void _transformJSObject(srcObject, dstObject, Function transform) {
  for (Object key in JS('!', '#.Object.keys(#)', global_, srcObject)) {
    JS('', '#[#] = #', dstObject, key,
        transform(JS('', '#[#]', srcObject, key)));
  }
}

/// The symbol used to store the cached `Type` object associated with a class.
final _typeObject = JS('', 'Symbol("typeObject")');

/// Given a WrappedType, return the internal runtime type object.
Object unwrapType(Type obj) => JS<_Type>('', '#', obj)._type;

// Marker class for generic functions, typedefs, and non-generic functions.
abstract class AbstractFunctionType extends DartType {}

/// Memo table for named argument groups. A named argument packet
/// {name1 : type1, ..., namen : typen} corresponds to the path
/// n, name1, type1, ...., namen, typen.  The element of the map
/// reached via this path (if any) is the canonical representative
/// for this packet.
final _fnTypeNamedArgMap = JS('', 'new Map()');

/// Memo table for positional argument groups. A positional argument
/// packet [type1, ..., typen] (required or optional) corresponds to
/// the path n, type1, ...., typen.  The element reached via
/// this path (if any) is the canonical representative for this
/// packet. Note that required and optional parameters packages
/// may have the same canonical representation.
final _fnTypeArrayArgMap = JS('', 'new Map()');

/// Memo table for function types. The index path consists of the
/// path length - 1, the returnType, the canonical positional argument
/// packet, and if present, the canonical optional or named argument
/// packet.  A level of indirection could be avoided here if desired.
final _fnTypeTypeMap = JS('', 'new Map()');

/// Memo table for small function types with no optional or named
/// arguments and less than a fixed n (currently 3) number of
/// required arguments.  Indexing into this table by the number
/// of required arguments yields a map which is indexed by the
/// argument types themselves.  The element reached via this
/// index path (if present) is the canonical function type.
final List _fnTypeSmallMap = JS('', '[new Map(), new Map(), new Map()]');

/// Memo table for generic function types. The index path consists of the
/// type parameters' bounds and the underlying function instantiated to its
/// bounds, subject to the same restrictions mentioned in _fnTypeTypeMap.
final _gFnTypeTypeMap = JS('', 'new Map()');

/// Pre-initialized type variables used to ensure that generic functions with
/// the same generic relationship structure but different names canonicalize
/// correctly.
final _typeVariablePool = <TypeVariable>[];

/// Returns a canonicalized sequence of type variables of size [count].
List<TypeVariable> _getCanonicalTypeFormals(int count) {
  while (count > _typeVariablePool.length) {
    _fillTypeVariable();
  }
  return _typeVariablePool.sublist(0, count);
}

/// Inserts a new type variable into _typeVariablePool according to a
/// pre-determined pattern.
///
/// The first 26 generics are alphanumerics; the remainder are represented as
/// T$N, where N increments from 0.
void _fillTypeVariable() {
  if (_typeVariablePool.length < 26) {
    _typeVariablePool
        .add(TypeVariable(String.fromCharCode(65 + _typeVariablePool.length)));
  } else {
    _typeVariablePool.add(TypeVariable('T${_typeVariablePool.length - 26}'));
  }
}

@NoReifyGeneric()
T _memoizeArray<T>(map, arr, T create()) => JS('', '''(() => {
  let len = $arr.length;
  $map = $_lookupNonTerminal($map, len);
  for (var i = 0; i < len-1; ++i) {
    $map = $_lookupNonTerminal($map, $arr[i]);
  }
  let result = $map.get($arr[len-1]);
  if (result !== void 0) return result;
  $map.set($arr[len-1], result = $create());
  return result;
})()''');

List _canonicalizeArray(List array, map) =>
    _memoizeArray(map, array, () => array);

// TODO(leafp): This only canonicalizes if the names are emitted
// in a consistent order.
_canonicalizeNamed(named, map) => JS('', '''(() => {
  let key = [];
  let names = $getOwnPropertyNames($named);
  for (var i = 0; i < names.length; ++i) {
    let name = names[i];
    let type = $named[name];
    key.push(name);
    key.push(type);
  }
  return $_memoizeArray($map, key, () => $named);
})()''');

// TODO(leafp): This handles some low hanging fruit, but
// really we should make all of this faster, and also
// handle more cases here.
FunctionType _createSmall(returnType, List required) => JS('', '''(() => {
  let count = $required.length;
  let map = $_fnTypeSmallMap[count];
  for (var i = 0; i < count; ++i) {
    map = $_lookupNonTerminal(map, $required[i]);
 }
 let result = map.get($returnType);
 if (result !== void 0) return result;
 result = ${new FunctionType(returnType, required, [], JS('', '{}'), JS('', '{}'))};
 map.set($returnType, result);
 return result;
})()''');

class FunctionType extends AbstractFunctionType {
  final Type returnType;
  final List args;
  final List optionals;
  // Named arguments native JS Object of the form { namedArgName: namedArgType }
  final named;
  final requiredNamed;
  String? _stringValue;

  /// Construct a function type.
  ///
  /// We eagerly normalize the argument types to avoid having to deal with this
  /// logic in multiple places.
  ///
  /// This code does best effort canonicalization.  It does not guarantee that
  /// all instances will share.
  ///
  /// Note: Generic function subtype checks assume types have been canonicalized
  /// when testing if type bounds are equal.
  static FunctionType create(
      returnType, List args, optionalArgs, requiredNamedArgs) {
    // Note that if optionalArgs is ever passed as an empty array or an empty
    // map, we can end up with semantically identical function types that don't
    // canonicalize to the same object since we won't fall into this fast path.
    var noOptionalArgs = optionalArgs == null && requiredNamedArgs == null;
    if (noOptionalArgs && JS<bool>('!', '#.length < 3', args)) {
      return _createSmall(returnType, args);
    }
    args = _canonicalizeArray(args, _fnTypeArrayArgMap);
    var keys = [];
    FunctionType Function() create;
    if (noOptionalArgs) {
      keys = [returnType, args];
      create =
          () => FunctionType(returnType, args, [], JS('', '{}'), JS('', '{}'));
    } else if (JS('!', '# instanceof Array', optionalArgs)) {
      var optionals =
          _canonicalizeArray(JS('', '#', optionalArgs), _fnTypeArrayArgMap);
      keys = [returnType, args, optionals];
      create = () =>
          FunctionType(returnType, args, optionals, JS('', '{}'), JS('', '{}'));
    } else {
      var named = _canonicalizeNamed(optionalArgs, _fnTypeNamedArgMap);
      var requiredNamed =
          _canonicalizeNamed(requiredNamedArgs, _fnTypeNamedArgMap);
      keys = [returnType, args, named, requiredNamed];
      create = () => FunctionType(returnType, args, [], named, requiredNamed);
    }
    return _memoizeArray(_fnTypeTypeMap, keys, create);
  }

  FunctionType(this.returnType, this.args, this.optionals, this.named,
      this.requiredNamed);

  toString() => name;

  int get requiredParameterCount => args.length;
  int get positionalParameterCount => args.length + optionals.length;

  getPositionalParameter(int i) {
    int n = args.length;
    return i < n ? args[i] : optionals[i + n];
  }

  /// Maps argument names to their canonicalized type.
  Map<String, Object> _createNameMap(List<Object?> names) {
    var result = <String, Object>{};
    // TODO: Remove this sort if ordering can be conserved.
    JS('', '#.sort()', names);
    for (var i = 0; JS<bool>('!', '# < #.length', i, names); ++i) {
      String name = JS('!', '#[#]', names, i);
      result[name] = JS('', '#[#]', named, name);
    }
    return result;
  }

  /// Maps optional named parameter names to their canonicalized type.
  Map<String, Object> getNamedParameters() =>
      _createNameMap(getOwnPropertyNames(named).toList());

  /// Maps required named parameter names to their canonicalized type.
  Map<String, Object> getRequiredNamedParameters() =>
      _createNameMap(getOwnPropertyNames(requiredNamed).toList());

  get name {
    if (_stringValue != null) return _stringValue!;
    var buffer = '(';
    for (var i = 0; JS<bool>('!', '# < #.length', i, args); ++i) {
      if (i > 0) {
        buffer += ', ';
      }
      buffer += typeName(JS('', '#[#]', args, i));
    }
    if (JS('!', '#.length > 0', optionals)) {
      if (JS('!', '#.length > 0', args)) buffer += ', ';
      buffer += '[';
      for (var i = 0; JS<bool>('!', '# < #.length', i, optionals); ++i) {
        if (i > 0) {
          buffer += ', ';
        }
        buffer += typeName(JS('', '#[#]', optionals, i));
      }
      buffer += ']';
    } else if (JS('!', 'Object.keys(#).length > 0 || Object.keys(#).length > 0',
        named, requiredNamed)) {
      if (JS('!', '#.length > 0', args)) buffer += ', ';
      buffer += '{';
      var names = getOwnPropertyNames(named);
      JS('', '#.sort()', names);
      for (var i = 0; JS<bool>('!', '# < #.length', i, names); i++) {
        if (i > 0) {
          buffer += ', ';
        }
        var typeNameString = typeName(JS('', '#[#[#]]', named, names, i));
        buffer += '$typeNameString ${JS('', '#[#]', names, i)}';
      }
      if (JS('!', 'Object.keys(#).length > 0 && #.length > 0', requiredNamed,
          names)) buffer += ', ';
      names = getOwnPropertyNames(requiredNamed);
      JS('', '#.sort()', names);
      for (var i = 0; JS<bool>('!', '# < #.length', i, names); i++) {
        if (i > 0) {
          buffer += ', ';
        }
        var typeNameString =
            typeName(JS('', '#[#[#]]', requiredNamed, names, i));
        buffer += 'required $typeNameString ${JS('', '#[#]', names, i)}';
      }
      buffer += '}';
    }
    var returnTypeName = typeName(returnType);
    buffer += ') => $returnTypeName';
    _stringValue = buffer;
    return buffer;
  }

  @JSExportName('is')
  bool is_T(obj) {
    if (JS('!', 'typeof # == "function"', obj)) {
      var actual = JS('', '#[#]', obj, _runtimeType);
      // If there's no actual type, it's a JS function.
      // Allow them to subtype all Dart function types.
      return actual == null || isSubtypeOf(actual, this);
    }
    return false;
  }

  @JSExportName('as')
  as_T(obj) {
    if (is_T(obj)) return obj;
    // TODO(nshahan) This could directly call castError after we no longer allow
    // a cast of null to succeed in weak mode.
    return cast(obj, this);
  }
}

/// A type variable, used by [GenericFunctionType] to represent a type formal.
class TypeVariable extends DartType {
  final String name;

  TypeVariable(this.name);

  toString() => name;
}

/// A helper data class for the subtype check algorithm to represent a generic
/// function type variable with its bound.
///
/// Instances of this class are created during subtype check operations to pass
/// information deeper into the algorithm. They are not canonicalized and should
/// be discarded after use.
class TypeVariableForSubtype extends DartType {
  /// The position of this type variable in the type variable list of a generic
  /// function.
  final int index;

  /// The bound for this type variable.
  ///
  /// Only nullable to avoid the cost of a late field within the subtype check.
  /// Should not be null after initial creation algorithm is complete.
  DartType? bound;

  TypeVariableForSubtype(this.index);
}

class Variance {
  static const int unrelated = 0;
  static const int covariant = 1;
  static const int contravariant = 2;
  static const int invariant = 3;
}

/// Uniquely identifies the runtime type object of a generic function.
///
/// We require that all objects stored in this object not have legacy
/// nullability wrappers.
class GenericFunctionTypeIdentifier extends AbstractFunctionType {
  final typeFormals;
  final typeBounds;
  final FunctionType function;
  String? _stringValue;

  GenericFunctionTypeIdentifier(
      this.typeFormals, this.typeBounds, this.function);

  /// Returns the string-representation of the first generic function
  /// with this runtime type object canonicalization.
  ///
  /// Type formal names may not correspond to those of the originating type.
  /// We should consider auto-generating these to avoid confusion.
  toString() {
    if (_stringValue != null) return _stringValue!;
    String s = "<";
    var typeFormals = this.typeFormals;
    var typeBounds = this.typeBounds;
    for (int i = 0, n = typeFormals.length; i < n; i++) {
      if (i != 0) s += ", ";
      s += JS<String>('!', '#[#].name', typeFormals, i);
      var bound = typeBounds[i];
      if (_equalType(bound, dynamic) ||
          JS<bool>('!', '# === #', bound, nullable(unwrapType(Object))) ||
          (!compileTimeFlag('soundNullSafety') && _equalType(bound, Object))) {
        // Do not print the bound when it is a top type. In weak mode the bounds
        // of Object and Object* will also be elided.
        continue;
      }
      s += " extends $bound";
    }
    s += ">" + this.function.toString();
    return this._stringValue = s;
  }
}

class GenericFunctionType extends AbstractFunctionType {
  final _instantiateTypeParts;
  @notNull
  final int formalCount;
  final _instantiateTypeBounds;
  final List<TypeVariable> _typeFormals;

  GenericFunctionType(instantiateTypeParts, this._instantiateTypeBounds)
      : _instantiateTypeParts = instantiateTypeParts,
        formalCount = JS('!', '#.length', instantiateTypeParts),
        _typeFormals = _typeFormalsFromFunction(instantiateTypeParts);

  List<TypeVariable> get typeFormals => _typeFormals;

  /// `true` if there are bounds on any of the generic type parameters.
  bool get hasTypeBounds => _instantiateTypeBounds != null;

  /// Checks that [typeArgs] satisfies the upper bounds of the [typeFormals],
  /// and throws a [TypeError] if they do not.
  void checkBounds(List<Object> typeArgs) {
    // If we don't have explicit type parameter bounds, the bounds default to
    // a top type, so there's nothing to check here.
    if (!hasTypeBounds) return;

    var bounds = instantiateTypeBounds(typeArgs);
    var typeFormals = this.typeFormals;
    for (var i = 0; i < typeArgs.length; i++) {
      checkTypeBound(typeArgs[i], bounds[i], typeFormals[i].name);
    }
  }

  FunctionType instantiate(typeArgs) {
    var parts = JS('', '#.apply(null, #)', _instantiateTypeParts, typeArgs);
    return FunctionType.create(JS('', '#[0]', parts), JS('', '#[1]', parts),
        JS('', '#[2]', parts), JS('', '#[3]', parts));
  }

  List<Object> instantiateTypeBounds(List typeArgs) {
    if (!hasTypeBounds) {
      // We omit the a bound to represent Object*. Other bounds are explicitly
      // represented, including Object, Object? and dynamic.
      // TODO(nshahan) Revisit this representation when more libraries have
      // migrated to null safety.
      return List<Object>.filled(formalCount, legacy(unwrapType(Object)));
    }
    // Bounds can be recursive or depend on other type parameters, so we need to
    // apply type arguments and return the resulting bounds.
    return JS<List<Object>>(
        '!', '#.apply(null, #)', _instantiateTypeBounds, typeArgs);
  }

  toString() {
    String s = "<";
    var typeFormals = this.typeFormals;
    var typeBounds = instantiateTypeBounds(typeFormals);
    for (int i = 0, n = typeFormals.length; i < n; i++) {
      if (i != 0) s += ", ";
      s += JS<String>('!', '#[#].name', typeFormals, i);
      var bound = typeBounds[i];
      if (JS('!', '# !== # && # !== #', bound, dynamic, bound, Object)) {
        s += " extends $bound";
      }
    }
    s += ">" + instantiate(typeFormals).toString();
    return s;
  }

  /// Given a [DartType] [type], if [type] is an uninstantiated
  /// parameterized type then instantiate the parameters to their
  /// bounds and return those type arguments.
  ///
  /// See the issue for the algorithm description:
  /// <https://github.com/dart-lang/sdk/issues/27526#issuecomment-260021397>
  List instantiateDefaultBounds() {
    /// Returns `true` if the default value for the type bound should be
    /// `dynamic`.
    ///
    /// Dart 2 with null safety uses dynamic as the default value for types
    /// without explicit bounds.
    ///
    /// This is similar to [_isTop] but removes the check for `void` (it can't
    /// be written as a bound) and adds a check of `Object*` in weak mode.
    bool defaultsToDynamic(type) {
      // Technically this is wrong, only implicit bounds of `Object?` and
      // `Object*` should default to dynamic but code that observes the
      // difference is rare.
      if (_equalType(type, dynamic)) return true;
      if (_jsInstanceOf(type, NullableType) ||
          (!compileTimeFlag('soundNullSafety') &&
              _jsInstanceOf(type, LegacyType))) {
        return _equalType(JS('!', '#.type', type), Object);
      }
      return false;
    }

    var typeFormals = this.typeFormals;

    // All type formals
    var all = HashMap<TypeVariable, int>.identity();
    // ground types, by index.
    //
    // For each index, this will be a ground type for the corresponding type
    // formal if known, or it will be the original TypeVariable if we are still
    // solving for it. This array is passed to `instantiateToBounds` as we are
    // progressively solving for type variables.
    var defaults = List<Object?>.filled(typeFormals.length, null);
    // not ground
    var partials = Map<TypeVariable, Object>.identity();

    var typeBounds = this.instantiateTypeBounds(typeFormals);
    for (var i = 0; i < typeFormals.length; i++) {
      var typeFormal = typeFormals[i];
      var bound = typeBounds[i];
      all[typeFormal] = i;
      if (defaultsToDynamic(bound)) {
        // TODO(nshahan) Persist the actual default values into the runtime so
        // they can be used here instead of using dynamic for all top types
        // implicit or explicit.
        defaults[i] = _dynamic;
      } else {
        defaults[i] = typeFormal;
        partials[typeFormal] = bound;
      }
    }

    bool hasFreeFormal(t) {
      if (partials.containsKey(t)) return true;

      // Ignore nullability wrappers.
      if (_jsInstanceOf(t, LegacyType) || _jsInstanceOf(t, NullableType)) {
        return hasFreeFormal(JS<Object>('!', '#.type', t));
      }
      // Generic classes and typedefs.
      var typeArgs = getGenericArgs(t);
      if (typeArgs != null) return typeArgs.any(hasFreeFormal);
      if (t is GenericFunctionType) {
        return hasFreeFormal(t.instantiate(t.typeFormals));
      }
      if (t is FunctionType) {
        return hasFreeFormal(t.returnType) || t.args.any(hasFreeFormal);
      }
      return false;
    }

    var hasProgress = true;
    while (hasProgress) {
      hasProgress = false;
      for (var typeFormal in partials.keys) {
        var partialBound = partials[typeFormal]!;
        if (!hasFreeFormal(partialBound)) {
          int index = all[typeFormal]!;
          defaults[index] = instantiateTypeBounds(defaults)[index];
          partials.remove(typeFormal);
          hasProgress = true;
          break;
        }
      }
    }

    // If we stopped making progress, and not all types are ground,
    // then the whole type is malbounded and an error should be reported
    // if errors are requested, and a partially completed type should
    // be returned.
    if (partials.isNotEmpty) {
      throwTypeError('Instantiate to bounds failed for type with '
          'recursive generic bounds: ${typeName(this)}. '
          'Try passing explicit type arguments.');
    }
    return defaults;
  }

  @notNull
  @JSExportName('is')
  bool is_T(obj) {
    if (JS('!', 'typeof # == "function"', obj)) {
      var actual = JS('', '#[#]', obj, _runtimeType);
      return actual != null && isSubtypeOf(actual, this);
    }
    return false;
  }

  @JSExportName('as')
  as_T(obj) {
    if (is_T(obj)) return obj;
    // TODO(nshahan) This could directly call castError after we no longer allow
    // a cast of null to succeed in weak mode.
    return cast(obj, this);
  }
}

List<TypeVariable> _typeFormalsFromFunction(Object? typeConstructor) {
  // Extract parameter names from the function parameters.
  //
  // This is not robust in general for user-defined JS functions, but it
  // should handle the functions generated by our compiler.
  //
  // TODO(jmesserly): names of TypeVariables are only used for display
  // purposes, such as when an error happens or if someone calls
  // `Type.toString()`. So we could recover them lazily rather than eagerly.
  // Alternatively we could synthesize new names.
  String str = JS('!', '#.toString()', typeConstructor);
  var hasParens = str[0] == '(';
  var end = str.indexOf(hasParens ? ')' : '=>');
  if (hasParens) {
    return str
        .substring(1, end)
        .split(',')
        .map((n) => TypeVariable(n.trim()))
        .toList();
  } else {
    return [TypeVariable(str.substring(0, end).trim())];
  }
}

/// Create a function type.
FunctionType fnType(returnType, List args,
        [@undefined optional, @undefined requiredNamed]) =>
    FunctionType.create(returnType, args, optional, requiredNamed);

/// Creates a generic function type from [instantiateFn] and [typeBounds].
///
/// A function type consists of two things:
/// * An instantiate function that takes type arguments and returns the
///   function signature in the form of a two element list. The first element
///   is the return type. The second element is a list of the argument types.
/// * A function that returns a list of upper bound constraints for each of
///   the type formals.
///
/// Both functions accept the type parameters, allowing us to substitute values.
/// The upper bound constraints can be omitted if all of the type parameters use
/// the default upper bound.
///
/// For example given the type <T extends Iterable<T>>(T) -> T, we can declare
/// this type with `gFnType(T => [T, [T]], T => [Iterable$(T)])`.
gFnType(instantiateFn, typeBounds) =>
    GenericFunctionType(instantiateFn, typeBounds);

/// Whether the given JS constructor [obj] is a Dart class type.
@notNull
bool isType(obj) => JS('', '#[#] === #', obj, _runtimeType, Type);

void checkTypeBound(
    @notNull Object type, @notNull Object bound, @notNull String name) {
  if (!isSubtypeOf(type, bound)) {
    throwTypeError('type `$type` does not extend `$bound` of `$name`.');
  }
}

@notNull
String typeName(type) {
  if (JS<bool>('!', '# === void 0', type)) return 'undefined type';
  if (JS<bool>('!', '# === null', type)) return 'null type';
  // Non-instance types
  if (_jsInstanceOf(type, DartType)) {
    return JS<String>('!', '#.toString()', type);
  }

  // Instance types
  var tag = JS('', '#[#]', type, _runtimeType);
  if (JS<bool>('!', '# === #', tag, Type)) {
    var name = JS<String>('!', '#.name', type);
    var args = getGenericArgs(type);
    if (args == null) return name;

    if (JS<bool>('!', '# == #', getGenericClass(type),
        getGenericClassStatic<JSArray>())) {
      name = 'List';
    }

    var result = name + '<';
    for (var i = 0; i < JS<int>('!', '#.length', args); ++i) {
      if (i > 0) result += ', ';
      result += typeName(JS('', '#[#]', args, i));
    }
    result += '>';
    return result;
  }
  // Test the JavaScript "truthiness" of `tag`.
  if (JS<bool>('!', '!!#', tag)) {
    return 'Not a type: ' + JS<String>('!', '#.name', tag);
  }
  return 'JSObject<' + JS<String>('!', '#.name', type) + '>';
}

/// Returns true if [ft1] <: [ft2].
@notNull
bool _isFunctionSubtype(@notNull FunctionType ft1, @notNull FunctionType ft2,
    @notNull bool strictMode) {
  var ret1 = ft1.returnType;
  var ret2 = ft2.returnType;

  var args1 = ft1.args;
  var args1Length = JS<int>('!', '#.length', args1);
  var args2 = ft2.args;
  var args2Length = JS<int>('!', '#.length', args2);

  if (args1Length > args2Length) {
    return false;
  }

  for (var i = 0; i < args1Length; ++i) {
    if (!_isSubtype(
        JS('!', '#[#]', args2, i), JS('!', '#[#]', args1, i), strictMode)) {
      return false;
    }
  }

  var optionals1 = ft1.optionals;
  var optionals1Length = JS<int>('!', '#.length', optionals1);
  var optionals2 = ft2.optionals;
  var optionals2Length = JS<int>('!', '#.length', optionals2);

  if (args1Length + optionals1Length < args2Length + optionals2Length) {
    return false;
  }

  var j = 0;
  for (var i = args1Length; i < args2Length; ++i, ++j) {
    if (!_isSubtype(JS('!', '#[#]', args2, i), JS('!', '#[#]', optionals1, j),
        strictMode)) {
      return false;
    }
  }

  for (var i = 0; i < optionals2Length; ++i, ++j) {
    if (!_isSubtype(JS('!', '#[#]', optionals2, i),
        JS('!', '#[#]', optionals1, j), strictMode)) {
      return false;
    }
  }

  // Named parameter invariants:
  // 1) All named params in the superclass are named params in the subclass.
  // 2) All required named params in the subclass are required named params
  //    in the superclass.
  // 3) With strict null checking disabled, we treat required named params as
  //    optional named params.
  var named1 = ft1.named;
  var requiredNamed1 = ft1.requiredNamed;
  var named2 = ft2.named;
  var requiredNamed2 = ft2.requiredNamed;
  if (!strictMode) {
    // In weak mode, treat required named params as optional named params.
    named1 = JS('!', 'Object.assign({}, #, #)', named1, requiredNamed1);
    named2 = JS('!', 'Object.assign({}, #, #)', named2, requiredNamed2);
    requiredNamed1 = JS('!', '{}');
    requiredNamed2 = JS('!', '{}');
  }

  var names = getOwnPropertyNames(requiredNamed1);
  var namesLength = JS<int>('!', '#.length', names);
  for (var i = 0; i < namesLength; ++i) {
    var name = JS('!', '#[#]', names, i);
    var n2 = JS('!', '#[#]', requiredNamed2, name);
    if (JS<bool>('!', '# === void 0', n2)) {
      return false;
    }
  }
  names = getOwnPropertyNames(named2);
  namesLength = JS<int>('!', '#.length', names);
  for (var i = 0; i < namesLength; ++i) {
    var name = JS('!', '#[#]', names, i);
    var n1 = JS('!', '#[#]', named1, name);
    var n2 = JS('!', '#[#]', named2, name);
    if (JS<bool>('!', '# === void 0', n1)) {
      return false;
    }
    if (!_isSubtype(n2, n1, strictMode)) {
      return false;
    }
  }
  names = getOwnPropertyNames(requiredNamed2);
  namesLength = JS<int>('!', '#.length', names);
  for (var i = 0; i < namesLength; ++i) {
    var name = JS('!', '#[#]', names, i);
    var n1 = JS('!', '#[#] || #[#]', named1, name, requiredNamed1, name);
    var n2 = JS('!', '#[#]', requiredNamed2, name);
    if (JS<bool>('!', '# === void 0', n1)) {
      return false;
    }
    if (!_isSubtype(n2, n1, strictMode)) {
      return false;
    }
  }

  return _isSubtype(ret1, ret2, strictMode);
}

/// Number of generic function type variables encountered so far during a
/// subtype check.
///
/// This continues to increase through nested generic function types but should
/// always be reset before performing a new subtype check.
@notNull
var _typeVariableCount = 0;

/// Returns true if [t1] <: [t2].
@notNull
bool isSubtypeOf(@notNull t1, @notNull t2) {
  // TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, so they're
  // dispatched on the type. Can we optimize the subtype relation too?
  var map = JS<Object>('!', '#[#]', t1, _subtypeCache);
  bool result = JS('', '#.get(#)', map, t2);
  if (JS('!', '# !== void 0', result)) return result;
  // Reset count before performing subtype check.
  _typeVariableCount = 0;
  var validSubtype = _isSubtype(t1, t2, true);
  if (!validSubtype && !compileTimeFlag('soundNullSafety')) {
    // Reset count before performing subtype check.
    _typeVariableCount = 0;
    validSubtype = _isSubtype(t1, t2, false);
    if (validSubtype) {
      // TODO(nshahan) Need more information to be helpful here.
      // File and line number that caused the subtype check?
      // Possibly break into debugger?
      _nullWarn("$t1 is not a subtype of $t2.");
    }
  }
  JS('', '#.set(#, #)', map, t2, validSubtype);
  return validSubtype;
}

@notNull
bool _isBottom(type, @notNull bool strictMode) =>
    _equalType(type, Never) || (!strictMode && _equalType(type, Null));

@notNull
bool _isTop(type) {
  if (_jsInstanceOf(type, NullableType))
    return JS('!', '#.type === #', type, Object);

  return _equalType(type, dynamic) || JS('!', '# === #', type, void_);
}

/// Wraps the JavaScript `instanceof` operator returning  `true` if [type] is an
/// instance of [cls].
///
/// This method is equivalent to:
///
///    JS<bool>('!', '# instanceof #', type, cls);
///
/// but the code is generated by the compiler directly (a low-tech way of
/// inlining).
@notNull
external bool _jsInstanceOf(type, cls);

/// Returns `true` if [type] is [cls].
///
/// This method is equivalent to:
///
///    JS<bool>('!', '# === #', type, unwrapType(cls));
///
/// but the code is generated by the compiler directly (a low-tech way of
/// inlining).
@notNull
external bool _equalType(type, cls);

/// Extracts the type argument as an unwrapped type preserving all forms of
/// nullability.
///
/// Acts as a way to bypass extra calls of [wrapType] and [unwrapType]. For
/// example `typeRep<Object?>()` emits `dart.nullable(core.Object)` directly.
@notNull
external Type typeRep<T>();

/// Extracts the type argument as an unwrapped type and performs a shallow
/// replacement of the nullability to a legacy type.
///
/// Acts as a way to bypass extra calls of [wrapType] and [unwrapType]. For
/// example `legacyTypeRep<Object>()` emits `dart.legacy(core.Object)` directly.
@notNull
external Type legacyTypeRep<T>();

@notNull
bool _isFutureOr(type) {
  var genericClass = getGenericClass(type);
  return JS<bool>('!', '# && # === #', genericClass, genericClass,
      getGenericClassStatic<FutureOr>());
}

@notNull
bool _isSubtype(t1, t2, @notNull bool strictMode) {
  if (!strictMode) {
    // Strip nullable types when performing check in weak mode.
    // TODO(nshahan) Investigate stripping off legacy types as well.
    if (_jsInstanceOf(t1, NullableType)) {
      t1 = JS<NullableType>('!', '#', t1).type;
    }
    if (_jsInstanceOf(t2, NullableType)) {
      t2 = JS<NullableType>('!', '#', t2).type;
    }
  }

  if (JS<bool>('!', '# === #', t1, t2)) {
    return true;
  }

  // Trivially true, "Right Top" or "Left Bottom".
  if (_isTop(t2) || _isBottom(t1, strictMode)) {
    return true;
  }

  // "Left Top".
  if (_equalType(t1, dynamic) || JS<bool>('!', '# === #', t1, void_)) {
    return _isSubtype(typeRep<Object?>(), t2, strictMode);
  }

  // "Right Object".
  if (_equalType(t2, Object)) {
    if (_isFutureOr(t1)) {
      var t1TypeArg = JS('', '#[0]', getGenericArgs(t1));
      return _isSubtype(t1TypeArg, typeRep<Object>(), strictMode);
    }

    if (_jsInstanceOf(t1, LegacyType)) {
      return _isSubtype(JS<LegacyType>('!', '#', t1).type, t2, strictMode);
    }

    if (_equalType(t1, Null) || _jsInstanceOf(t1, NullableType)) {
      // Checks for t1 is dynamic or void already performed in "Left Top" test.
      return false;
    }
    return true;
  }

  // "Left Null".
  if (_equalType(t1, Null)) {
    if (_isFutureOr(t2)) {
      var t2TypeArg = JS('', '#[0]', getGenericArgs(t2));
      return _isSubtype(typeRep<Null>(), t2TypeArg, strictMode);
    }

    return _equalType(t2, Null) ||
        _jsInstanceOf(t2, LegacyType) ||
        _jsInstanceOf(t2, NullableType);
  }

  // "Left Legacy".
  if (_jsInstanceOf(t1, LegacyType)) {
    return _isSubtype(JS<LegacyType>('!', '#', t1).type, t2, strictMode);
  }

  // "Right Legacy".
  if (_jsInstanceOf(t2, LegacyType)) {
    return _isSubtype(
        t1, nullable(JS<LegacyType>('!', '#', t2).type), strictMode);
  }

  // Handle FutureOr<T> union type.
  if (_isFutureOr(t1)) {
    var t1TypeArg = JS('!', '#[0]', getGenericArgs(t1));
    if (_isFutureOr(t2)) {
      var t2TypeArg = JS('!', '#[0]', getGenericArgs(t2));
      // FutureOr<A> <: FutureOr<B> if A <: B
      if (_isSubtype(t1TypeArg, t2TypeArg, strictMode)) {
        return true;
      }
    }

    // given t1 is Future<A> | A, then:
    // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
    var t1Future = JS('!', '#(#)', getGenericClassStatic<Future>(), t1TypeArg);
    // Known to handle the case FutureOr<Null> <: Future<Null>.
    return _isSubtype(t1Future, t2, strictMode) &&
        _isSubtype(t1TypeArg, t2, strictMode);
  }

  // "Left Nullable".
  if (_jsInstanceOf(t1, NullableType)) {
    return _isSubtype(JS<NullableType>('!', '#', t1).type, t2, strictMode) &&
        _isSubtype(typeRep<Null>(), t2, strictMode);
  }

  if (_isFutureOr(t2)) {
    // given t2 is Future<A> | A, then:
    // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
    var t2TypeArg = JS('!', '#[0]', getGenericArgs(t2));
    var t2Future = JS('!', '#(#)', getGenericClassStatic<Future>(), t2TypeArg);
    return _isSubtype(t1, t2Future, strictMode) ||
        _isSubtype(t1, t2TypeArg, strictMode);
  }

  // "Right Nullable".
  if (_jsInstanceOf(t2, NullableType)) {
    return _isSubtype(t1, JS<NullableType>('!', '#', t2).type, strictMode) ||
        _isSubtype(t1, typeRep<Null>(), strictMode);
  }

  // "Traditional" name-based subtype check.  Avoid passing
  // function types to the class subtype checks, since we don't
  // currently distinguish between generic typedefs and classes.
  if (!_jsInstanceOf(t2, AbstractFunctionType)) {
    // t2 is an interface type.

    if (_jsInstanceOf(t1, AbstractFunctionType)) {
      // Function types are only subtypes of interface types `Function` (and top
      // types, handled already above).
      return _equalType(t2, Function);
    }

    // Even though lazy and anonymous JS types are natural subtypes of
    // LegacyJavaScriptObject, JS types should be treated as mutual subtypes of
    // each other. This allows users to be able to interface with both extension
    // types on LegacyJavaScriptObject and package:js using the same object.
    //
    // Therefore, the following relationships hold true:
    //
    // LegacyJavaScriptObject <: package:js types
    // package:js types <: LegacyJavaScriptObject

    if (_isInterfaceSubtype(
            t1, typeRep<LegacyJavaScriptObject>(), strictMode) &&
        // TODO: Since package:js types are instances of PackageJSType and
        // we don't have a mechanism to determine if *some* package:js type
        // implements t2. This will possibly require keeping a map of these
        // relationships for this subtyping check. For now, this will only
        // work if t2 is also a PackageJSType.
        _isInterfaceSubtype(_pkgJSTypeForSubtyping, t2, strictMode)) {
      return true;
    }

    if (_isInterfaceSubtype(
            typeRep<LegacyJavaScriptObject>(), t2, strictMode) &&
        _isInterfaceSubtype(t1, _pkgJSTypeForSubtyping, strictMode)) {
      return true;
    }

    // Compare two interface types.
    return _isInterfaceSubtype(t1, t2, strictMode);
  }

  // Function subtyping.
  if (!_jsInstanceOf(t1, AbstractFunctionType)) {
    return false;
  }

  // Handle generic functions.
  if (_jsInstanceOf(t1, GenericFunctionType)) {
    if (!_jsInstanceOf(t2, GenericFunctionType)) {
      return false;
    }

    // Given generic functions g1 and g2, g1 <: g2 iff:
    //
    //     g1<TFresh> <: g2<TFresh>
    //
    // where TFresh is a list of fresh type variables that both g1 and g2 will
    // be instantiated with.
    var formalCount = JS<GenericFunctionType>('!', '#', t1).formalCount;
    if (formalCount != JS<GenericFunctionType>('!', '#', t2).formalCount) {
      return false;
    }

    // Fresh type variables will be used to instantiate generic functions.
    List<Object> fresh1;
    List<Object> fresh2;

    // Without type bounds all will instantiate to dynamic. Only need to check
    // further if at least one of the functions has type bounds.
    if (JS<bool>('!', '#.hasTypeBounds || #.hasTypeBounds', t1, t2)) {
      // Create two sets of fresh type variables that can store their bounds so
      // they can be considered in recursive calls.
      fresh1 = JS('!', 'new Array(#)', formalCount);
      fresh2 = JS('!', 'new Array(#)', formalCount);
      for (var i = 0; i < formalCount; i++, _typeVariableCount++) {
        JS('!', '#[#] = #', fresh1, i,
            TypeVariableForSubtype(_typeVariableCount));
        JS('!', '#[#] = #', fresh2, i,
            TypeVariableForSubtype(_typeVariableCount));
      }
      var t1Bounds =
          JS<GenericFunctionType>('!', '#', t1).instantiateTypeBounds(fresh1);
      var t2Bounds =
          JS<GenericFunctionType>('!', '#', t2).instantiateTypeBounds(fresh2);

      for (var i = 0; i < formalCount; i++) {
        var t1Bound = JS<Object>('!', '#[#]', t1Bounds, i);
        var t2Bound = JS<Object>('!', '#[#]', t2Bounds, i);

        // Check the bounds of the type parameters of g1 and g2. Given a type
        // parameter `T1 extends B1` from g1, and a type parameter `T2 extends
        // B2` from g2, we must ensure that B1 and B2 are mutual subtypes.
        //
        // (Note there is no variance in the type bounds of type parameters of
        // generic functions).
        if (JS<bool>('!', '# != #', t1Bound, t2Bound)) {
          if (!(_isSubtype(t1Bound, t2Bound, strictMode) &&
              _isSubtype(t2Bound, t1Bound, strictMode))) {
            return false;
          }
        }
        // Assign bounds to be used in the `_isInterfaceSubtype` check later as
        // this subtype check continues.
        JS('', '#[#].bound = #', fresh1, i, t1Bound);
        JS('', '#[#].bound = #', fresh2, i, t2Bound);
      }
    } else {
      // Using either function's type formals will work as long as they're both
      // instantiated with the same ones. The instantiate operation is
      // guaranteed to avoid capture because it does not depend on its
      // TypeVariable objects, rather it uses JS function parameters to ensure
      // correct binding.
      fresh1 = JS<GenericFunctionType>('!', '#', t1).typeFormals;
      fresh2 = fresh1;
    }

    t1 = JS<GenericFunctionType>('!', '#', t1).instantiate(fresh1);
    t2 = JS<GenericFunctionType>('!', '#', t2).instantiate(fresh2);
  } else if (_jsInstanceOf(t2, GenericFunctionType)) {
    return false;
  }

  // Handle non-generic functions.
  return _isFunctionSubtype(JS<FunctionType>('!', '#', t1),
      JS<FunctionType>('!', '#', t2), strictMode);
}

@notNull
bool _isInterfaceSubtype(t1, t2, @notNull bool strictMode) {
  // Instances of PackageJSType are all subtypes of each other.
  if (_jsInstanceOf(t1, PackageJSType) && _jsInstanceOf(t2, PackageJSType)) {
    return true;
  }

  if (JS<bool>('!', '# === #', t1, t2)) {
    return true;
  }
  if (_equalType(t1, Object)) {
    return false;
  }

  // Classes cannot subtype `Function` or vice versa.
  if (_equalType(t1, Function) || _equalType(t2, Function)) {
    return false;
  }

  // If t1 is a JS Object, we may not hit core.Object.
  if (t1 == null) {
    return _equalType(t2, Object) || _equalType(t2, dynamic);
  }

  if (_jsInstanceOf(t1, TypeVariableForSubtype)) {
    if (_jsInstanceOf(t2, TypeVariableForSubtype)) {
      // Bounds were already checked to be subtypes of each other in the
      // generic function section of `_isSubtype()` so just check these type
      // variables share the same index in their respective signatures.
      return JS<TypeVariableForSubtype>('!', '#', t1).index ==
          JS<TypeVariableForSubtype>('!', '#', t2).index;
    }

    // If t1 <: bound <: t2 then t1 <: t2.
    return _isSubtype(
        JS<TypeVariableForSubtype>('!', '#', t1).bound, t2, strictMode);
  }

  // Check if t1 and t2 have the same raw type.  If so, check covariance on
  // type parameters.
  var raw1 = getGenericClass(t1);
  var raw2 = getGenericClass(t2);
  if (raw1 != null && JS<bool>('!', '# == #', raw1, raw2)) {
    var typeArguments1 = getGenericArgs(t1);
    var typeArguments2 = getGenericArgs(t2);
    if (JS<bool>('!', '#.length != #.length', typeArguments1, typeArguments2)) {
      assertFailed('Internal type check failure.');
    }
    var variances = getGenericArgVariances(t1);
    for (var i = 0; i < JS<int>('!', '#.length', typeArguments1); ++i) {
      // When using implicit variance, variances will be undefined and
      // considered covariant.
      var varianceType = JS('!', '# && #[#]', variances, variances, i);
      var typeArg1 = JS('!', '#[#]', typeArguments1, i);
      var typeArg2 = JS('!', '#[#]', typeArguments2, i);
      if (JS<bool>('!', '# === void 0 || # == #', varianceType, varianceType,
          Variance.covariant)) {
        if (!_isSubtype(typeArg1, typeArg2, strictMode)) {
          return false;
        }
      } else if (JS<bool>(
          '!', '# == #', varianceType, Variance.contravariant)) {
        if (!_isSubtype(typeArg2, typeArg1, strictMode)) {
          return false;
        }
      } else if (JS<bool>('!', '# == #', varianceType, Variance.invariant)) {
        if (!_isSubtype(typeArg1, typeArg2, strictMode) ||
            !_isSubtype(typeArg2, typeArg1, strictMode)) {
          return false;
        }
      }
    }
    return true;
  }

  if (_isInterfaceSubtype(JS('', '#.__proto__', t1), t2, strictMode)) {
    return true;
  }

  // Check mixin.
  var m1 = getMixin(t1);
  if (m1 != null && _isInterfaceSubtype(m1, t2, strictMode)) {
    return true;
  }

  // Check interfaces.
  var getInterfaces = getImplements(t1);
  if (getInterfaces != null) {
    for (var i1 in getInterfaces()) {
      if (_isInterfaceSubtype(i1, t2, strictMode)) {
        return true;
      }
    }
  }
  return false;
}

Object? extractTypeArguments<T>(T instance, Function f) {
  if (instance == null) {
    throw ArgumentError('Cannot extract type of null instance.');
  }
  var type = unwrapType(T);
  // Get underlying type from nullability wrappers if needed.
  type = JS<Object>('!', '#.type || #', type, type);

  if (type is AbstractFunctionType || _isFutureOr(type)) {
    throw ArgumentError('Cannot extract from non-class type ($type).');
  }
  var typeArguments = getGenericArgs(type);
  if (typeArguments!.isEmpty) {
    throw ArgumentError('Cannot extract from non-generic type ($type).');
  }
  var supertype = _getMatchingSupertype(getReifiedType(instance), type);
  // The signature of this method guarantees that instance is a T, so we
  // should have a valid non-empty list at this point.
  assert(supertype != null);
  var typeArgs = getGenericArgs(supertype);
  assert(typeArgs != null && typeArgs.isNotEmpty);
  return dgcall(f, typeArgs, []);
}

/// Infers type variables based on a series of [trySubtypeMatch] calls, followed
/// by [getInferredTypes] to return the type.
class _TypeInferrer {
  final Map<TypeVariable, TypeConstraint> _typeVariables;

  /// Creates a [TypeConstraintGatherer] which is prepared to gather type
  /// constraints for the given type parameters.
  _TypeInferrer(Iterable<TypeVariable> typeVariables)
      : _typeVariables = Map.fromIterables(
            typeVariables, typeVariables.map((_) => TypeConstraint()));

  /// Returns the inferred types based on the current constraints.
  List<Object>? getInferredTypes() {
    var result = <Object>[];
    for (var constraint in _typeVariables.values) {
      // Prefer the known bound, if any.
      if (constraint.lower != null) {
        result.add(constraint.lower!);
      } else if (constraint.upper != null) {
        result.add(constraint.upper!);
      } else {
        return null;
      }
    }
    return result;
  }

  /// Tries to match [subtype] against [supertype].
  ///
  /// If the match succeeds, the resulting type constraints are recorded for
  /// later use by [computeConstraints].  If the match fails, the set of type
  /// constraints is unchanged.
  bool trySubtypeMatch(Object subtype, Object supertype) =>
      _isSubtypeMatch(subtype, supertype);

  void _constrainLower(TypeVariable parameter, Object lower) {
    _typeVariables[parameter]!._constrainLower(lower);
  }

  void _constrainUpper(TypeVariable parameter, Object upper) {
    _typeVariables[parameter]!._constrainUpper(upper);
  }

  bool _isFunctionSubtypeMatch(FunctionType subtype, FunctionType supertype) {
    // A function type `(M0,..., Mn, [M{n+1}, ..., Mm]) -> R0` is a subtype
    // match for a function type `(N0,..., Nk, [N{k+1}, ..., Nr]) -> R1` with
    // respect to `L` under constraints `C0 + ... + Cr + C`
    // - If `R0` is a subtype match for a type `R1` with respect to `L` under
    //   constraints `C`:
    // - If `n <= k` and `r <= m`.
    // - And for `i` in `0...r`, `Ni` is a subtype match for `Mi` with respect
    //   to `L` under constraints `Ci`.
    // Function types with named parameters are treated analogously to the
    // positional parameter case above.
    // A generic function type `<T0 extends B0, ..., Tn extends Bn>F0` is a
    // subtype match for a generic function type `<S0 extends B0, ..., Sn
    // extends Bn>F1` with respect to `L` under constraints `Cl`:
    // - If `F0[Z0/T0, ..., Zn/Tn]` is a subtype match for `F0[Z0/S0, ...,
    //   Zn/Sn]` with respect to `L` under constraints `C`, where each `Zi` is a
    //   fresh type variable with bound `Bi`.
    // - And `Cl` is `C` with each constraint replaced with its closure with
    //   respect to `[Z0, ..., Zn]`.
    if (subtype.requiredParameterCount > supertype.requiredParameterCount) {
      return false;
    }
    if (subtype.positionalParameterCount < supertype.positionalParameterCount) {
      return false;
    }
    // Test the return types.
    if (supertype.returnType is! VoidType &&
        !_isSubtypeMatch(subtype.returnType, supertype.returnType)) {
      return false;
    }

    // Test the parameter types.
    for (int i = 0, n = supertype.positionalParameterCount; i < n; ++i) {
      if (!_isSubtypeMatch(supertype.getPositionalParameter(i),
          subtype.getPositionalParameter(i))) {
        return false;
      }
    }

    // Named parameter invariants:
    // 1) All named params in the superclass are named params in the subclass.
    // 2) All required named params in the subclass are required named params
    //    in the superclass.
    // 3) With strict null checking disabled, we treat required named params as
    //    optional named params.
    var supertypeNamed = supertype.getNamedParameters();
    var supertypeRequiredNamed = supertype.getRequiredNamedParameters();
    var subtypeNamed = supertype.getNamedParameters();
    var subtypeRequiredNamed = supertype.getRequiredNamedParameters();
    if (!compileTimeFlag('soundNullSafety')) {
      // In weak mode, treat required named params as optional named params.
      supertypeNamed = {...supertypeNamed, ...supertypeRequiredNamed};
      subtypeNamed = {...subtypeNamed, ...subtypeRequiredNamed};
      supertypeRequiredNamed = {};
      subtypeRequiredNamed = {};
    }
    for (var name in subtypeRequiredNamed.keys) {
      var supertypeParamType = supertypeRequiredNamed[name];
      if (supertypeParamType == null) return false;
    }
    for (var name in supertypeNamed.keys) {
      var subtypeParamType = subtypeNamed[name];
      if (subtypeParamType == null) return false;
      if (!_isSubtypeMatch(supertypeNamed[name]!, subtypeParamType)) {
        return false;
      }
    }
    for (var name in supertypeRequiredNamed.keys) {
      var subtypeParamType = subtypeRequiredNamed[name] ?? subtypeNamed[name]!;
      if (!_isSubtypeMatch(supertypeRequiredNamed[name]!, subtypeParamType)) {
        return false;
      }
    }
    return true;
  }

  bool _isInterfaceSubtypeMatch(Object subtype, Object supertype) {
    // A type `P<M0, ..., Mk>` is a subtype match for `P<N0, ..., Nk>` with
    // respect to `L` under constraints `C0 + ... + Ck`:
    // - If `Mi` is a subtype match for `Ni` with respect to `L` under
    //   constraints `Ci`.
    // A type `P<M0, ..., Mk>` is a subtype match for `Q<N0, ..., Nj>` with
    // respect to `L` under constraints `C`:
    // - If `R<B0, ..., Bj>` is the superclass of `P<M0, ..., Mk>` and `R<B0,
    //   ..., Bj>` is a subtype match for `Q<N0, ..., Nj>` with respect to `L`
    //   under constraints `C`.
    // - Or `R<B0, ..., Bj>` is one of the interfaces implemented by `P<M0, ...,
    //   Mk>` (considered in lexical order) and `R<B0, ..., Bj>` is a subtype
    //   match for `Q<N0, ..., Nj>` with respect to `L` under constraints `C`.
    // - Or `R<B0, ..., Bj>` is a mixin into `P<M0, ..., Mk>` (considered in
    //   lexical order) and `R<B0, ..., Bj>` is a subtype match for `Q<N0, ...,
    //   Nj>` with respect to `L` under constraints `C`.

    // Note that since kernel requires that no class may only appear in the set
    // of supertypes of a given type more than once, the order of the checks
    // above is irrelevant; we just need to find the matched superclass,
    // substitute, and then iterate through type variables.
    var matchingSupertype = _getMatchingSupertype(subtype, supertype);
    if (matchingSupertype == null) return false;

    var matchingTypeArgs = getGenericArgs(matchingSupertype)!;
    var supertypeTypeArgs = getGenericArgs(supertype)!;
    for (int i = 0; i < supertypeTypeArgs.length; i++) {
      if (!_isSubtypeMatch(matchingTypeArgs[i], supertypeTypeArgs[i])) {
        return false;
      }
    }
    return true;
  }

  /// Attempts to match [subtype] as a subtype of [supertype], gathering any
  /// constraints discovered in the process.
  ///
  /// If a set of constraints was found, `true` is returned and the caller
  /// may proceed to call [computeConstraints].  Otherwise, `false` is returned.
  ///
  /// In the case where `false` is returned, some bogus constraints may have
  /// been added to [_protoConstraints].  It is the caller's responsibility to
  /// discard them if necessary.
  // TODO(#40326) Update to support null safety subtyping algorithm.
  bool _isSubtypeMatch(Object subtype, Object supertype) {
    // A type variable `T` in `L` is a subtype match for any type schema `Q`:
    // - Under constraint `T <: Q`.
    if (subtype is TypeVariable && _typeVariables.containsKey(subtype)) {
      _constrainUpper(subtype, supertype);
      return true;
    }
    // A type schema `Q` is a subtype match for a type variable `T` in `L`:
    // - Under constraint `Q <: T`.
    if (supertype is TypeVariable && _typeVariables.containsKey(supertype)) {
      _constrainLower(supertype, subtype);
      return true;
    }
    // Any two equal types `P` and `Q` are subtype matches under no constraints.
    // Note: to avoid making the algorithm quadratic, we just check for
    // identical().  If P and Q are equal but not identical, recursing through
    // the types will give the proper result.
    if (identical(subtype, supertype)) return true;
    // Any type `P` is a subtype match for `dynamic`, `Object`, or `void` under
    // no constraints.
    if (_isTop(supertype)) return true;
    // `Null` is a subtype match for any type `Q` under no constraints.
    // Note that nullable types will change this.
    if (_equalType(subtype, Null)) return true;

    // Handle FutureOr<T> union type.
    if (_isFutureOr(subtype)) {
      var subtypeArg = getGenericArgs(subtype)![0];
      if (_isFutureOr(supertype)) {
        // `FutureOr<P>` is a subtype match for `FutureOr<Q>` with respect to `L`
        // under constraints `C`:
        // - If `P` is a subtype match for `Q` with respect to `L` under constraints
        //   `C`.
        var supertypeArg = getGenericArgs(supertype)![0];
        return _isSubtypeMatch(subtypeArg, supertypeArg);
      }

      // `FutureOr<P>` is a subtype match for `Q` with respect to `L` under
      // constraints `C0 + C1`:
      // - If `Future<P>` is a subtype match for `Q` with respect to `L` under
      //   constraints `C0`.
      // - And `P` is a subtype match for `Q` with respect to `L` under
      //   constraints `C1`.
      var subtypeFuture =
          JS<Object>('!', '#(#)', getGenericClassStatic<Future>(), subtypeArg);
      return _isSubtypeMatch(subtypeFuture, supertype) &&
          _isSubtypeMatch(subtypeArg!, supertype);
    }

    if (_isFutureOr(supertype)) {
      // `P` is a subtype match for `FutureOr<Q>` with respect to `L` under
      // constraints `C`:
      // - If `P` is a subtype match for `Future<Q>` with respect to `L` under
      //   constraints `C`.
      // - Or `P` is not a subtype match for `Future<Q>` with respect to `L` under
      //   constraints `C`
      //   - And `P` is a subtype match for `Q` with respect to `L` under
      //     constraints `C`
      var supertypeArg = getGenericArgs(supertype)![0];
      var supertypeFuture = JS<Object>(
          '!', '#(#)', getGenericClassStatic<Future>(), supertypeArg);
      return _isSubtypeMatch(subtype, supertypeFuture) ||
          _isSubtypeMatch(subtype, supertypeArg);
    }

    // A type variable `T` not in `L` with bound `P` is a subtype match for the
    // same type variable `T` with bound `Q` with respect to `L` under
    // constraints `C`:
    // - If `P` is a subtype match for `Q` with respect to `L` under constraints
    //   `C`.
    if (subtype is TypeVariable) {
      return supertype is TypeVariable && identical(subtype, supertype);
    }
    if (subtype is GenericFunctionType) {
      if (supertype is GenericFunctionType) {
        // Given generic functions g1 and g2, g1 <: g2 iff:
        //
        //     g1<TFresh> <: g2<TFresh>
        //
        // where TFresh is a list of fresh type variables that both g1 and g2 will
        // be instantiated with.
        var formalCount = subtype.formalCount;
        if (formalCount != supertype.formalCount) return false;

        // Using either function's type formals will work as long as they're
        // both instantiated with the same ones. The instantiate operation is
        // guaranteed to avoid capture because it does not depend on its
        // TypeVariable objects, rather it uses JS function parameters to ensure
        // correct binding.
        var fresh = supertype.typeFormals;

        // Check the bounds of the type parameters of g1 and g2.
        // given a type parameter `T1 extends U1` from g1, and a type parameter
        // `T2 extends U2` from g2, we must ensure that:
        //
        //      U2 <: U1
        //
        // (Note the reversal of direction -- type formal bounds are
        // contravariant, similar to the function's formal parameter types).
        //
        var t1Bounds = subtype.instantiateTypeBounds(fresh);
        var t2Bounds = supertype.instantiateTypeBounds(fresh);
        // TODO(jmesserly): we could optimize for the common case of no bounds.
        for (var i = 0; i < formalCount; i++) {
          if (!_isSubtypeMatch(t2Bounds[i], t1Bounds[i])) {
            return false;
          }
        }
        return _isFunctionSubtypeMatch(
            subtype.instantiate(fresh), supertype.instantiate(fresh));
      } else {
        return false;
      }
    } else if (supertype is GenericFunctionType) {
      return false;
    }

    // A type `P` is a subtype match for `Function` with respect to `L` under no
    // constraints:
    // - If `P` implements a call method.
    // - Or if `P` is a function type.
    // TODO(paulberry): implement this case.
    // A type `P` is a subtype match for a type `Q` with respect to `L` under
    // constraints `C`:
    // - If `P` is an interface type which implements a call method of type `F`,
    //   and `F` is a subtype match for a type `Q` with respect to `L` under
    //   constraints `C`.
    // TODO(paulberry): implement this case.
    if (subtype is FunctionType) {
      if (supertype is! FunctionType) {
        if (_equalType(supertype, Function) || _equalType(supertype, Object)) {
          return true;
        } else {
          return false;
        }
      }
      if (supertype is FunctionType) {
        return _isFunctionSubtypeMatch(subtype, supertype);
      }
    }
    return _isInterfaceSubtypeMatch(subtype, supertype);
  }

  bool _isTop(Object type) =>
      identical(type, _dynamic) ||
      identical(type, void_) ||
      _equalType(type, Object);
}

/// A constraint on a type parameter that we're inferring.
class TypeConstraint {
  /// The lower bound of the type being constrained.  This bound must be a
  /// subtype of the type being constrained.
  Object? lower;

  /// The upper bound of the type being constrained.  The type being constrained
  /// must be a subtype of this bound.
  Object? upper;

  void _constrainLower(Object type) {
    var _lower = lower;
    if (_lower != null) {
      if (isSubtypeOf(_lower, type)) {
        // nothing to do, existing lower bound is lower than the new one.
        return;
      }
      if (!isSubtypeOf(type, _lower)) {
        // Neither bound is lower and we don't have GLB, so use bottom type.
        type = unwrapType(Null);
      }
    }
    lower = type;
  }

  void _constrainUpper(Object type) {
    var _upper = upper;
    if (_upper != null) {
      if (isSubtypeOf(type, _upper)) {
        // nothing to do, existing upper bound is higher than the new one.
        return;
      }
      if (!isSubtypeOf(_upper, type)) {
        // Neither bound is higher and we don't have LUB, so use top type.
        type = unwrapType(Object);
      }
    }
    upper = type;
  }

  String toString() => '${typeName(lower)} <: <type> <: ${typeName(upper)}';
}

/// Finds a supertype of [subtype] that matches the class [supertype], but may
/// contain different generic type arguments.
Object? _getMatchingSupertype(Object? subtype, Object supertype) {
  if (identical(subtype, supertype)) return supertype;
  if (subtype == null || _equalType(subtype, Object)) return null;

  var subclass = getGenericClass(subtype);
  var superclass = getGenericClass(supertype);
  if (subclass != null && identical(subclass, superclass)) {
    return subtype; // matching supertype found!
  }

  var result = _getMatchingSupertype(JS('', '#.__proto__', subtype), supertype);
  if (result != null) return result;

  // Check mixin.
  var mixin = getMixin(subtype);
  if (mixin != null) {
    result = _getMatchingSupertype(mixin, supertype);
    if (result != null) return result;
  }

  // Check interfaces.
  var getInterfaces = getImplements(subtype);
  if (getInterfaces != null) {
    for (var iface in getInterfaces()) {
      result = _getMatchingSupertype(iface, supertype);
      if (result != null) return result;
    }
  }

  return null;
}
