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

import '../common/names.dart';
import '../common_elements.dart';
import '../options.dart';
import '../serialization/serialization.dart';
import '../util/util.dart' show equalElements, equalSets, identicalElements;
import 'entities.dart';

/// Hierarchy to describe types in Dart.
///
/// This hierarchy is a super hierarchy of the use-case specific hierarchies
/// used in different parts of the compiler. This hierarchy abstracts details
/// not generally needed or required for the Dart type hierarchy. For instance,
/// the hierarchy in 'resolution_types.dart' has properties supporting lazy
/// computation (like computeAlias) and distinctions between 'Foo' and
/// 'Foo<dynamic>', features that are not needed for code generation and not
/// supported from kernel.
///
/// Current only 'resolution_types.dart' implement this hierarchy but when the
/// compiler moves to use [Entity] instead of [Element] this hierarchy can be
/// implemented directly but other entity systems, for instance based directly
/// on kernel ir without the need for [Element].

extension on DataSource {
  List<DartType> _readDartTypes(
      List<FunctionTypeVariable> functionTypeVariables) {
    int count = readInt();
    List<DartType> types = List<DartType>.filled(count, null);
    for (int index = 0; index < count; index++) {
      types[index] = DartType.readFromDataSource(this, functionTypeVariables);
    }
    return types;
  }
}

extension on DataSink {
  void _writeDartTypes(
      List<DartType> types, List<FunctionTypeVariable> functionTypeVariables) {
    writeInt(types.length);
    for (DartType type in types) {
      type.writeToDataSink(this, functionTypeVariables);
    }
  }
}

abstract class DartType {
  const DartType();

  factory DartType.readFromDataSource(
      DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
    DartTypeKind kind = source.readEnum(DartTypeKind.values);
    switch (kind) {
      case DartTypeKind.none:
        return null;
      case DartTypeKind.legacyType:
        return LegacyType._readFromDataSource(source, functionTypeVariables);
      case DartTypeKind.nullableType:
        return NullableType._readFromDataSource(source, functionTypeVariables);
      case DartTypeKind.neverType:
        return NeverType._readFromDataSource(source, functionTypeVariables);
      case DartTypeKind.voidType:
        return VoidType._readFromDataSource(source, functionTypeVariables);
      case DartTypeKind.typeVariable:
        return TypeVariableType._readFromDataSource(
            source, functionTypeVariables);
      case DartTypeKind.functionTypeVariable:
        return FunctionTypeVariable._readFromDataSource(
            source, functionTypeVariables);
      case DartTypeKind.functionType:
        return FunctionType._readFromDataSource(source, functionTypeVariables);
      case DartTypeKind.interfaceType:
        return InterfaceType._readFromDataSource(source, functionTypeVariables);
      case DartTypeKind.dynamicType:
        return DynamicType._readFromDataSource(source, functionTypeVariables);
      case DartTypeKind.erasedType:
        return ErasedType._readFromDataSource(source, functionTypeVariables);
      case DartTypeKind.anyType:
        return AnyType._readFromDataSource(source, functionTypeVariables);
      case DartTypeKind.futureOr:
        return FutureOrType._readFromDataSource(source, functionTypeVariables);
    }
    throw UnsupportedError('Unexpected DartTypeKind $kind');
  }

  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables);

  /// Returns the base type if this is a [LegacyType] or [NullableType] and
  /// returns this type otherwise.
  DartType get withoutNullability => this;

  /// Whether this type contains a type variable.
  bool get containsTypeVariables => false;

  /// Whether this type contains a free class type variable or function type
  /// variable.
  // TODO(sra): Review uses of [containsTypeVariables] for update with
  // [containsFreeTypeVariables].
  bool get containsFreeTypeVariables =>
      _ContainsFreeTypeVariablesVisitor().run(this);

  /// Is `true` if this type is the `Object` type defined in `dart:core`.
  bool get isObject => false;

  /// Is `true` if this type is the `Null` type defined in `dart:core`.
  bool get isNull => false;

  /// Applies [f] to each occurrence of a [TypeVariableType] within this
  /// type. This excludes function type variables, whether free or bound.
  void forEachTypeVariable(f(TypeVariableType variable)) {}

  /// Calls the visit method on [visitor] corresponding to this type.
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument);

  bool _equals(DartType other, _Assumptions assumptions);

  @override
  String toString() => toStructuredText(null, null);

  String toStructuredText(DartTypes dartTypes, CompilerOptions options) =>
      _DartTypeToStringVisitor(dartTypes, options).run(this);
}

/// Pairs of [FunctionTypeVariable]s that are currently assumed to be
/// equivalent.
///
/// This is used to compute the equivalence relation on types coinductively.
class _Assumptions {
  Map<FunctionTypeVariable, Set<FunctionTypeVariable>> _assumptionMap =
      <FunctionTypeVariable, Set<FunctionTypeVariable>>{};

  void _addAssumption(FunctionTypeVariable a, FunctionTypeVariable b) {
    _assumptionMap
        .putIfAbsent(a, () => new Set<FunctionTypeVariable>.identity())
        .add(b);
  }

  /// Assume that [a] and [b] are equivalent.
  void assume(FunctionTypeVariable a, FunctionTypeVariable b) {
    _addAssumption(a, b);
    _addAssumption(b, a);
  }

  void assumePairs(
      List<FunctionTypeVariable> as, List<FunctionTypeVariable> bs) {
    int length = as.length;
    assert(length == bs.length);
    for (int i = 0; i < length; i++) {
      assume(as[i], bs[i]);
    }
  }

  void _removeAssumption(FunctionTypeVariable a, FunctionTypeVariable b) {
    Set<FunctionTypeVariable> set = _assumptionMap[a];
    if (set != null) {
      set.remove(b);
      if (set.isEmpty) {
        _assumptionMap.remove(a);
      }
    }
  }

  /// Remove the assumption that [a] and [b] are equivalent.
  void forget(FunctionTypeVariable a, FunctionTypeVariable b) {
    _removeAssumption(a, b);
    _removeAssumption(b, a);
  }

  void forgetPairs(
      List<FunctionTypeVariable> as, List<FunctionTypeVariable> bs) {
    int length = as.length;
    assert(length == bs.length);
    for (int i = 0; i < length; i++) {
      forget(as[i], bs[i]);
    }
  }

  /// Returns `true` if [a] and [b] are assumed to be equivalent.
  bool isAssumed(FunctionTypeVariable a, FunctionTypeVariable b) {
    return _assumptionMap[a]?.contains(b) ?? false;
  }

  @override
  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.write('_Assumptions(');
    String comma = '';
    _assumptionMap
        .forEach((FunctionTypeVariable a, Set<FunctionTypeVariable> set) {
      sb.write('$comma$a (${identityHashCode(a)})->'
          '{${set.map((b) => '$b (${identityHashCode(b)})').join(',')}}');
      comma = ',';
    });
    sb.write(')');
    return sb.toString();
  }
}

class LegacyType extends DartType {
  final DartType baseType;

  const LegacyType._(this.baseType);

  factory LegacyType._readFromDataSource(
      DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
    DartType baseType =
        DartType.readFromDataSource(source, functionTypeVariables);
    return LegacyType._(baseType);
  }

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.legacyType);
    baseType.writeToDataSink(sink, functionTypeVariables);
  }

  @override
  DartType get withoutNullability => baseType;

  @override
  bool get containsTypeVariables => baseType.containsTypeVariables;

  @override
  void forEachTypeVariable(f(TypeVariableType variable)) {
    baseType.forEachTypeVariable(f);
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitLegacyType(this, argument);

  @override
  int get hashCode => baseType.hashCode * 31;

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! LegacyType) return false;
    return _equalsInternal(other, null);
  }

  @override
  bool _equals(DartType other, _Assumptions assumptions) {
    if (identical(this, other)) return true;
    if (other is! LegacyType) return false;
    return _equalsInternal(other, assumptions);
  }

  bool _equalsInternal(LegacyType other, _Assumptions assumptions) =>
      baseType._equals(other.baseType, assumptions);
}

class NullableType extends DartType {
  final DartType baseType;

  const NullableType._(this.baseType);

  factory NullableType._readFromDataSource(
      DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
    DartType baseType =
        DartType.readFromDataSource(source, functionTypeVariables);
    return NullableType._(baseType);
  }

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.nullableType);
    baseType.writeToDataSink(sink, functionTypeVariables);
  }

  @override
  DartType get withoutNullability => baseType;

  @override
  bool get containsTypeVariables => baseType.containsTypeVariables;

  @override
  void forEachTypeVariable(f(TypeVariableType variable)) {
    baseType.forEachTypeVariable(f);
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitNullableType(this, argument);

  @override
  int get hashCode => baseType.hashCode * 37;

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! NullableType) return false;
    return _equalsInternal(other, null);
  }

  @override
  bool _equals(DartType other, _Assumptions assumptions) {
    if (identical(this, other)) return true;
    if (other is! NullableType) return false;
    return _equalsInternal(other, assumptions);
  }

  bool _equalsInternal(NullableType other, _Assumptions assumptions) =>
      baseType._equals(other.baseType, assumptions);
}

class InterfaceType extends DartType {
  final ClassEntity element;
  final List<DartType> typeArguments;

  InterfaceType._allocate(this.element, this.typeArguments);

  factory InterfaceType._(ClassEntity element, List<DartType> typeArguments) {
    assert(typeArguments.every((e) => e != null));
    if (typeArguments.isEmpty) typeArguments = const [];
    return InterfaceType._allocate(element, typeArguments);
  }

  factory InterfaceType._readFromDataSource(
      DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
    ClassEntity element = source.readClass();
    List<DartType> typeArguments = source._readDartTypes(functionTypeVariables);
    return InterfaceType._(element, typeArguments);
  }

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.interfaceType);
    sink.writeClass(element);
    sink._writeDartTypes(typeArguments, functionTypeVariables);
  }

  @override
  bool get isObject =>
      element.name == 'Object' &&
      element.library.canonicalUri == Uris.dart_core;

  @override
  bool get isNull =>
      element.name == 'Null' && element.library.canonicalUri == Uris.dart_core;

  @override
  bool get containsTypeVariables =>
      typeArguments.any((type) => type.containsTypeVariables);

  @override
  void forEachTypeVariable(f(TypeVariableType variable)) {
    typeArguments.forEach((type) => type.forEachTypeVariable(f));
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitInterfaceType(this, argument);

  @override
  int get hashCode {
    int hash = element.hashCode;
    for (DartType argument in typeArguments) {
      int argumentHash = argument != null ? argument.hashCode : 0;
      hash = 17 * hash + 3 * argumentHash;
    }
    return hash;
  }

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! InterfaceType) return false;
    return _equalsInternal(other, null);
  }

  @override
  bool _equals(DartType other, _Assumptions assumptions) {
    if (identical(this, other)) return true;
    if (other is! InterfaceType) return false;
    return _equalsInternal(other, assumptions);
  }

  bool _equalsInternal(InterfaceType other, _Assumptions assumptions) {
    return identical(element, other.element) &&
        _equalTypes(typeArguments, other.typeArguments, assumptions);
  }
}

class TypeVariableType extends DartType {
  final TypeVariableEntity element;

  const TypeVariableType._(this.element);

  factory TypeVariableType._readFromDataSource(
      DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
    TypeVariableEntity element = source.readTypeVariable();
    return TypeVariableType._(element);
  }

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.typeVariable);
    sink.writeTypeVariable(element);
  }

  @override
  bool get containsTypeVariables => true;

  @override
  void forEachTypeVariable(f(TypeVariableType variable)) {
    f(this);
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitTypeVariableType(this, argument);

  @override
  int get hashCode => 17 * element.hashCode;

  @override
  bool operator ==(other) =>
      identical(this, other) ||
      other is TypeVariableType && identical(other.element, element);

  @override
  bool _equals(DartType other, _Assumptions assumptions) => this == other;
}

/// A type variable declared on a function type.
///
/// For instance `T` in
///     void Function<T>(T t)
///
/// Such a type variable is different from a [TypeVariableType] because it
/// doesn't have a unique identity; is is equal to any other
/// [FunctionTypeVariable] used similarly in another structurally equivalent
/// function type.
class FunctionTypeVariable extends DartType {
  /// The index of this type within the type variables of the declaring function
  /// type.
  final int index;

  /// The bound of this function type variable.
  DartType _bound;

  FunctionTypeVariable._(this.index);

  factory FunctionTypeVariable._readFromDataSource(
      DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
    int index = source.readInt();
    assert(0 <= index && index < functionTypeVariables.length);
    return functionTypeVariables[index];
  }

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    int index = functionTypeVariables.indexOf(this);
    if (index == -1) {
      // TODO(johnniwinther): Avoid free variables.
      const DynamicType._().writeToDataSink(sink, functionTypeVariables);
    } else {
      sink.writeEnum(DartTypeKind.functionTypeVariable);
      sink.writeInt(index);
    }
  }

  DartType get bound {
    assert(_bound != null, "Bound has not been set.");
    return _bound;
  }

  void set bound(DartType value) {
    assert(_bound == null, "Bound has already been set.");
    _bound = value;
  }

  @override
  bool _equals(DartType other, _Assumptions assumptions) {
    if (identical(this, other)) return true;
    if (other is! FunctionTypeVariable) return false;
    if (assumptions != null) return assumptions.isAssumed(this, other);
    return false;
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitFunctionTypeVariable(this, argument);
}

class NeverType extends DartType {
  const NeverType._();

  factory NeverType._readFromDataSource(
      DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
    return const NeverType._();
  }

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.neverType);
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitNeverType(this, argument);

  @override
  int get hashCode => 43;

  @override
  bool operator ==(other) => identical(this, other) || other is NeverType;

  @override
  bool _equals(DartType other, _Assumptions assumptions) => this == other;
}

class VoidType extends DartType {
  const VoidType._();

  factory VoidType._readFromDataSource(DataSource source,
          List<FunctionTypeVariable> functionTypeVariables) =>
      const VoidType._();

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.voidType);
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitVoidType(this, argument);

  @override
  int get hashCode => 6007;

  @override
  bool operator ==(other) => identical(this, other) || other is VoidType;

  @override
  bool _equals(DartType other, _Assumptions assumptions) => this == other;
}

class DynamicType extends DartType {
  const DynamicType._();

  factory DynamicType._readFromDataSource(DataSource source,
          List<FunctionTypeVariable> functionTypeVariables) =>
      const DynamicType._();

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.dynamicType);
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitDynamicType(this, argument);

  @override
  int get hashCode => 91;

  @override
  bool operator ==(other) => identical(this, other) || other is DynamicType;

  @override
  bool _equals(DartType other, _Assumptions assumptions) => this == other;
}

class ErasedType extends DartType {
  const ErasedType._();

  factory ErasedType._readFromDataSource(DataSource source,
          List<FunctionTypeVariable> functionTypeVariables) =>
      const ErasedType._();

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.erasedType);
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitErasedType(this, argument);

  @override
  int get hashCode => 119;

  @override
  bool operator ==(other) => identical(this, other) || other is ErasedType;

  @override
  bool _equals(DartType other, _Assumptions assumptions) => this == other;
}

/// Represents a type which is simultaneously top and bottom.
///
/// This is not a standard Dart type, but an extension of the standard Dart type
/// system for dart2js. Because 'any' is both top and bottom, it is useful for
/// ensuring that type checks succeed so that we can avoid spurious failures
/// when our analysis is incorrect or incomplete.
///
/// Use cases include:
/// * Representing inscrutable JS-interop types.
/// * Representing types appearing as generic method bounds which contain type
/// variables. (See issue 33422.)
class AnyType extends DartType {
  const AnyType._();

  factory AnyType._readFromDataSource(DataSource source,
          List<FunctionTypeVariable> functionTypeVariables) =>
      const AnyType._();

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.anyType);
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitAnyType(this, argument);

  @override
  int get hashCode => 95;

  @override
  bool operator ==(other) => identical(this, other) || other is AnyType;

  @override
  bool _equals(DartType other, _Assumptions assumptions) => this == other;
}

class FunctionType extends DartType {
  final DartType returnType;
  final List<DartType> parameterTypes;
  final List<DartType> optionalParameterTypes;

  /// The names of all named parameters ordered lexicographically.
  final List<String> namedParameters;

  /// The names of the required named parameters.
  final Set<String> requiredNamedParameters;

  /// The types of the named parameters in the order corresponding to the
  /// [namedParameters].
  final List<DartType> namedParameterTypes;

  final List<FunctionTypeVariable> typeVariables;

  FunctionType._allocate(
      this.returnType,
      this.parameterTypes,
      this.optionalParameterTypes,
      this.namedParameters,
      this.requiredNamedParameters,
      this.namedParameterTypes,
      this.typeVariables) {
    assert(returnType != null, 'Invalid return type in $this.');
    assert(!parameterTypes.contains(null), 'Invalid parameter types in $this.');
    assert(!optionalParameterTypes.contains(null),
        'Invalid optional parameter types in $this.');
    assert(
        !namedParameters.contains(null), 'Invalid named parameters in $this.');
    assert(!requiredNamedParameters.contains(null),
        'Invalid required named parameters in $this.');
    assert(!namedParameterTypes.contains(null),
        'Invalid named parameter types in $this.');
    assert(!typeVariables.contains(null), 'Invalid type variables in $this.');
  }

  factory FunctionType._(
      DartType returnType,
      List<DartType> parameterTypes,
      List<DartType> optionalParameterTypes,
      List<String> namedParameters,
      Set<String> requiredNamedParameters,
      List<DartType> namedParameterTypes,
      List<FunctionTypeVariable> typeVariables) {
    // Canonicalize empty collections to constants to save storage.
    if (parameterTypes.isEmpty) parameterTypes = const [];
    if (optionalParameterTypes.isEmpty) optionalParameterTypes = const [];
    if (namedParameters.isEmpty) namedParameters = const [];
    if (namedParameterTypes.isEmpty) namedParameterTypes = const [];
    if (requiredNamedParameters.isEmpty) requiredNamedParameters = const {};
    if (typeVariables.isEmpty) typeVariables = const [];

    return FunctionType._allocate(
        returnType,
        parameterTypes,
        optionalParameterTypes,
        namedParameters,
        requiredNamedParameters,
        namedParameterTypes,
        typeVariables);
  }

  factory FunctionType._readFromDataSource(
      DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
    int typeVariableCount = source.readInt();
    List<FunctionTypeVariable> typeVariables =
        List<FunctionTypeVariable>.generate(
            typeVariableCount, (int index) => FunctionTypeVariable._(index));
    functionTypeVariables = List<FunctionTypeVariable>.of(functionTypeVariables)
      ..addAll(typeVariables);
    for (int index = 0; index < typeVariableCount; index++) {
      typeVariables[index].bound =
          DartType.readFromDataSource(source, functionTypeVariables);
    }
    DartType returnType =
        DartType.readFromDataSource(source, functionTypeVariables);
    List<DartType> parameterTypes =
        source._readDartTypes(functionTypeVariables);
    List<DartType> optionalParameterTypes =
        source._readDartTypes(functionTypeVariables);
    List<DartType> namedParameterTypes =
        source._readDartTypes(functionTypeVariables);
    List<String> namedParameters =
        List<String>.filled(namedParameterTypes.length, null);
    var requiredNamedParameters = <String>{};
    for (int i = 0; i < namedParameters.length; i++) {
      namedParameters[i] = source.readString();
      if (source.readBool()) requiredNamedParameters.add(namedParameters[i]);
    }
    return FunctionType._(
        returnType,
        parameterTypes,
        optionalParameterTypes,
        namedParameters,
        requiredNamedParameters,
        namedParameterTypes,
        typeVariables);
  }

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.functionType);
    functionTypeVariables = List<FunctionTypeVariable>.of(functionTypeVariables)
      ..addAll(typeVariables);
    sink.writeInt(typeVariables.length);
    for (FunctionTypeVariable variable in typeVariables) {
      variable.bound.writeToDataSink(sink, functionTypeVariables);
    }
    returnType.writeToDataSink(sink, functionTypeVariables);
    sink._writeDartTypes(parameterTypes, functionTypeVariables);
    sink._writeDartTypes(optionalParameterTypes, functionTypeVariables);
    sink._writeDartTypes(namedParameterTypes, functionTypeVariables);
    for (String namedParameter in namedParameters) {
      sink.writeString(namedParameter);
      sink.writeBool(requiredNamedParameters.contains(namedParameter));
    }
  }

  @override
  bool get containsTypeVariables {
    return typeVariables.any((type) => type.bound.containsTypeVariables) ||
        returnType.containsTypeVariables ||
        parameterTypes.any((type) => type.containsTypeVariables) ||
        optionalParameterTypes.any((type) => type.containsTypeVariables) ||
        namedParameterTypes.any((type) => type.containsTypeVariables);
  }

  @override
  void forEachTypeVariable(f(TypeVariableType variable)) {
    typeVariables.forEach((type) => type.bound.forEachTypeVariable(f));
    returnType.forEachTypeVariable(f);
    parameterTypes.forEach((type) => type.forEachTypeVariable(f));
    optionalParameterTypes.forEach((type) => type.forEachTypeVariable(f));
    namedParameterTypes.forEach((type) => type.forEachTypeVariable(f));
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitFunctionType(this, argument);

  @override
  int get hashCode {
    int hash = 3 * returnType.hashCode;
    for (DartType parameter in parameterTypes) {
      hash = 19 * hash + 5 * parameter.hashCode;
    }
    for (DartType parameter in optionalParameterTypes) {
      hash = 23 * hash + 7 * parameter.hashCode;
    }
    for (String name in namedParameters) {
      hash = 29 * hash + 11 * name.hashCode;
    }
    for (DartType parameter in namedParameterTypes) {
      hash = 31 * hash + 13 * parameter.hashCode;
    }
    for (String name in requiredNamedParameters) {
      hash = 37 * hash + 17 * name.hashCode;
    }
    return hash;
  }

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! FunctionType) return false;
    return _equalsInternal(other, null);
  }

  @override
  bool _equals(DartType other, _Assumptions assumptions) {
    if (identical(this, other)) return true;
    if (other is! FunctionType) return false;
    return _equalsInternal(other, assumptions);
  }

  bool _equalsInternal(FunctionType other, _Assumptions assumptions) {
    if (typeVariables.length != other.typeVariables.length) return false;
    assumptions ??= _Assumptions();
    assumptions.assumePairs(typeVariables, other.typeVariables);
    try {
      for (int index = 0; index < typeVariables.length; index++) {
        if (!typeVariables[index]
            .bound
            ._equals(other.typeVariables[index].bound, assumptions)) {
          return false;
        }
      }
      return returnType._equals(other.returnType, assumptions) &&
          _equalTypes(parameterTypes, other.parameterTypes, assumptions) &&
          _equalTypes(optionalParameterTypes, other.optionalParameterTypes,
              assumptions) &&
          equalElements(namedParameters, other.namedParameters) &&
          equalSets(requiredNamedParameters, other.requiredNamedParameters) &&
          _equalTypes(
              namedParameterTypes, other.namedParameterTypes, assumptions);
    } finally {
      assumptions.forgetPairs(typeVariables, other.typeVariables);
    }
  }
}

class FutureOrType extends DartType {
  final DartType typeArgument;

  const FutureOrType._(this.typeArgument);

  factory FutureOrType._readFromDataSource(
      DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
    DartType typeArgument =
        DartType.readFromDataSource(source, functionTypeVariables);
    return FutureOrType._(typeArgument);
  }

  @override
  void writeToDataSink(
      DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
    sink.writeEnum(DartTypeKind.futureOr);
    typeArgument.writeToDataSink(sink, functionTypeVariables);
  }

  @override
  bool get containsTypeVariables => typeArgument.containsTypeVariables;

  @override
  void forEachTypeVariable(f(TypeVariableType variable)) {
    typeArgument.forEachTypeVariable(f);
  }

  @override
  R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
      visitor.visitFutureOrType(this, argument);

  @override
  int get hashCode => typeArgument.hashCode * 13;

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! FutureOrType) return false;
    return _equalsInternal(other, null);
  }

  @override
  bool _equals(DartType other, _Assumptions assumptions) {
    if (identical(this, other)) return true;
    if (other is! FutureOrType) return false;
    return _equalsInternal(other, assumptions);
  }

  bool _equalsInternal(FutureOrType other, _Assumptions assumptions) {
    return typeArgument._equals(other.typeArgument, assumptions);
  }
}

bool _equalTypes(List<DartType> a, List<DartType> b, _Assumptions assumptions) {
  if (a.length != b.length) return false;
  for (int index = 0; index < a.length; index++) {
    if (!a[index]._equals(b[index], assumptions)) {
      return false;
    }
  }
  return true;
}

abstract class DartTypeVisitor<R, A> {
  const DartTypeVisitor();

  R visit(covariant DartType type, A argument) => type.accept(this, argument);

  R visitLegacyType(covariant LegacyType type, A argument) => null;

  R visitNullableType(covariant NullableType type, A argument) => null;

  R visitNeverType(covariant NeverType type, A argument) => null;

  R visitVoidType(covariant VoidType type, A argument) => null;

  R visitTypeVariableType(covariant TypeVariableType type, A argument) => null;

  R visitFunctionTypeVariable(
          covariant FunctionTypeVariable type, A argument) =>
      null;

  R visitFunctionType(covariant FunctionType type, A argument) => null;

  R visitInterfaceType(covariant InterfaceType type, A argument) => null;

  R visitDynamicType(covariant DynamicType type, A argument) => null;

  R visitErasedType(covariant ErasedType type, A argument) => null;

  R visitAnyType(covariant AnyType type, A argument) => null;

  R visitFutureOrType(covariant FutureOrType type, A argument) => null;
}

abstract class BaseDartTypeVisitor<R, A> extends DartTypeVisitor<R, A> {
  const BaseDartTypeVisitor();

  R visitType(covariant DartType type, A argument);

  @override
  R visitLegacyType(covariant LegacyType type, A argument) =>
      visitType(type, argument);

  @override
  R visitNullableType(covariant NullableType type, A argument) =>
      visitType(type, argument);

  @override
  R visitNeverType(covariant NeverType type, A argument) =>
      visitType(type, argument);

  @override
  R visitVoidType(covariant VoidType type, A argument) =>
      visitType(type, argument);

  @override
  R visitTypeVariableType(covariant TypeVariableType type, A argument) =>
      visitType(type, argument);

  @override
  R visitFunctionTypeVariable(
          covariant FunctionTypeVariable type, A argument) =>
      visitType(type, argument);

  @override
  R visitFunctionType(covariant FunctionType type, A argument) =>
      visitType(type, argument);

  @override
  R visitInterfaceType(covariant InterfaceType type, A argument) =>
      visitType(type, argument);

  @override
  R visitDynamicType(covariant DynamicType type, A argument) =>
      visitType(type, argument);

  @override
  R visitErasedType(covariant ErasedType type, A argument) =>
      visitType(type, argument);

  @override
  R visitAnyType(covariant AnyType type, A argument) =>
      visitType(type, argument);

  @override
  R visitFutureOrType(covariant FutureOrType type, A argument) =>
      visitType(type, argument);
}

class _LegacyErasureVisitor extends DartTypeVisitor<DartType, Null> {
  final DartTypes _dartTypes;

  _LegacyErasureVisitor(this._dartTypes);

  DartType erase(DartType type) => visit(type, null);

  List<DartType> eraseList(List<DartType> types) {
    List<DartType> erasedTypes = types.map(erase).toList();
    return identicalElements(erasedTypes, types) ? types : erasedTypes;
  }

  @override
  DartType visit(DartType type, Null _) => type.accept(this, _);

  @override
  DartType visitLegacyType(LegacyType type, Null _) => erase(type.baseType);

  @override
  DartType visitNullableType(NullableType type, Null _) {
    var baseType = erase(type.baseType);
    if (identical(baseType, type.baseType)) return type;
    return _dartTypes.nullableType(baseType);
  }

  @override
  NeverType visitNeverType(NeverType type, Null _) => type;

  @override
  VoidType visitVoidType(VoidType type, Null _) => type;

  @override
  TypeVariableType visitTypeVariableType(TypeVariableType type, Null _) => type;

  @override
  FunctionTypeVariable visitFunctionTypeVariable(
          FunctionTypeVariable type, Null _) =>
      type;

  @override
  FunctionType visitFunctionType(FunctionType type, Null _) {
    var returnType = erase(type.returnType);
    var parameterTypes = eraseList(type.parameterTypes);
    var optionalParameterTypes = eraseList(type.optionalParameterTypes);
    var namedParameterTypes = eraseList(type.namedParameterTypes);

    var oldTypeVariables = type.typeVariables;
    var length = oldTypeVariables.length;

    List<FunctionTypeVariable> typeVariables =
        List<FunctionTypeVariable>.filled(length, null);
    List<FunctionTypeVariable> erasableTypeVariables = [];
    List<FunctionTypeVariable> erasedTypeVariables = [];
    for (int i = 0; i < length; i++) {
      var oldTypeVariable = oldTypeVariables[i];
      var oldBound = oldTypeVariable.bound;
      var bound = erase(oldBound);
      if (identical(bound, oldBound)) {
        typeVariables[i] = oldTypeVariable;
      } else {
        var typeVariable = _dartTypes.functionTypeVariable(i)..bound = bound;
        typeVariables[i] = typeVariable;
        erasableTypeVariables.add(oldTypeVariable);
        erasedTypeVariables.add(typeVariable);
      }
    }

    if (identical(returnType, type.returnType) &&
        identical(parameterTypes, type.parameterTypes) &&
        identical(optionalParameterTypes, type.optionalParameterTypes) &&
        identical(namedParameterTypes, type.namedParameterTypes) &&
        erasableTypeVariables.isEmpty) return type;

    return _dartTypes.subst(
        erasedTypeVariables,
        erasableTypeVariables,
        _dartTypes.functionType(
            returnType,
            parameterTypes,
            optionalParameterTypes,
            type.namedParameters,
            type.requiredNamedParameters,
            namedParameterTypes,
            typeVariables));
  }

  @override
  InterfaceType visitInterfaceType(InterfaceType type, Null _) {
    var typeArguments = eraseList(type.typeArguments);
    if (identical(typeArguments, type.typeArguments)) return type;
    return _dartTypes.interfaceType(type.element, typeArguments);
  }

  @override
  DynamicType visitDynamicType(DynamicType type, Null _) => type;

  @override
  ErasedType visitErasedType(ErasedType type, Null _) => type;

  @override
  AnyType visitAnyType(AnyType type, Null _) => type;

  @override
  DartType visitFutureOrType(FutureOrType type, Null _) {
    var typeArgument = erase(type.typeArgument);
    if (identical(typeArgument, type.typeArgument)) return type;
    return _dartTypes.futureOrType(typeArgument);
  }
}

abstract class DartTypeSubstitutionVisitor<A>
    extends DartTypeVisitor<DartType, A> {
  DartTypes get dartTypes;

  // The input type is a DAG and we must preserve the sharing.
  Map<DartType, DartType> _map = Map.identity();

  DartType _mapped(DartType oldType, DartType newType) {
    assert(_map[oldType] == null);
    return _map[oldType] = newType;
  }

  /// Returns the replacement for the type variable [type]. Returns the original
  /// [type] if not substituted. The substitution algorithm sometimes visits the
  /// same subterm more than once. When this happens, [freshReference] is `true`
  /// on only one visit. This allows the substitution visitor to count the
  /// number of times the replacement term occurs in the final term.
  DartType substituteTypeVariableType(
      TypeVariableType type, A argument, bool freshReference);

  /// Returns the replacement for the function type variable [type]. Returns the
  /// original [type] if not substituted. The substitution algorithm sometimes
  /// visits the same subterm more than once. When this happens,
  /// [freshReference] is `true` on only one visit. This allows the substitution
  /// visitor to count the number of times the replacement term occurs in the
  /// final term.
  DartType substituteFunctionTypeVariable(
          FunctionTypeVariable type, A argument, bool freshReference) =>
      type;

  @override
  DartType visitLegacyType(covariant LegacyType type, A argument) {
    DartType probe = _map[type];
    if (probe != null) return probe;

    DartType newBaseType = visit(type.baseType, argument);
    // Create a new type only if necessary.
    if (identical(type.baseType, newBaseType)) {
      return _mapped(type, type);
    }
    return _mapped(type, dartTypes.legacyType(newBaseType));
  }

  @override
  DartType visitNullableType(covariant NullableType type, A argument) {
    DartType probe = _map[type];
    if (probe != null) return probe;

    DartType newBaseType = visit(type.baseType, argument);
    // Create a new type only if necessary.
    if (identical(type.baseType, newBaseType)) {
      return _mapped(type, type);
    }
    return _mapped(type, dartTypes.nullableType(newBaseType));
  }

  @override
  DartType visitNeverType(covariant NeverType type, A argument) => type;

  @override
  DartType visitTypeVariableType(covariant TypeVariableType type, A argument) {
    return substituteTypeVariableType(type, argument, true);
  }

  @override
  DartType visitFunctionTypeVariable(
      covariant FunctionTypeVariable type, A argument) {
    // Function type variables are added to the map only for type variables that
    // need to be replaced with updated bounds.
    DartType probe = _map[type];
    if (probe != null) return probe;
    return substituteFunctionTypeVariable(type, argument, true);
  }

  @override
  DartType visitVoidType(covariant VoidType type, A argument) => type;

  @override
  DartType visitFunctionType(covariant FunctionType type, A argument) {
    DartType probe = _map[type];
    if (probe != null) return probe;

    List<FunctionTypeVariable> newTypeVariables =
        _handleFunctionTypeVariables(type.typeVariables, argument);

    DartType newReturnType = visit(type.returnType, argument);
    List<DartType> newParameterTypes =
        _substTypes(type.parameterTypes, argument);
    List<DartType> newOptionalParameterTypes =
        _substTypes(type.optionalParameterTypes, argument);
    List<DartType> newNamedParameterTypes =
        _substTypes(type.namedParameterTypes, argument);

    // Create a new type only if necessary.
    if (identical(type.typeVariables, newTypeVariables) &&
        identical(type.returnType, newReturnType) &&
        identical(type.parameterTypes, newParameterTypes) &&
        identical(type.optionalParameterTypes, newOptionalParameterTypes) &&
        identical(type.namedParameterTypes, newNamedParameterTypes)) {
      return _mapped(type, type);
    }

    return _mapped(
        type,
        dartTypes.functionType(
            newReturnType,
            newParameterTypes,
            newOptionalParameterTypes,
            type.namedParameters,
            type.requiredNamedParameters,
            newNamedParameterTypes,
            newTypeVariables));
  }

  List<FunctionTypeVariable> _handleFunctionTypeVariables(
      List<FunctionTypeVariable> variables, A argument) {
    if (variables.isEmpty) return variables;

    // Type variables may depend on each other. Consider:
    //
    //     <A extends List<B>,
    //      B extends Set<A>,
    //      C extends D,
    //      D extends Map<B, F>>(){}
    //
    // A and B have a cycle but are not changed by the subsitution of F->G. C is
    // indirectly changed by the substitution of F. When D is replaced by `D2
    // extends Map<B,G>`, C must be replaced by `C2 extends D2`.

    List<FunctionTypeVariable> undecided = variables.toList();
    List<FunctionTypeVariable> newVariables;

    _DependencyCheck<A> dependencyCheck = _DependencyCheck<A>(this, argument);

    bool changed = true;
    while (changed) {
      changed = false;
      for (int i = 0; i < undecided.length; i++) {
        FunctionTypeVariable variable = undecided[i];
        if (variable == null) continue;
        if (dependencyCheck.run(variable.bound)) {
          changed = true;
          undecided[i] = null;
          newVariables ??= variables.toList();
          FunctionTypeVariable newVariable =
              dartTypes.functionTypeVariable(variable.index);
          newVariables[i] = newVariable;
          _mapped(variable, newVariable);
        }
      }
    }
    if (newVariables == null) return variables;

    // Substitute the bounds of the new variables;
    for (int i = 0; i < newVariables.length; i++) {
      FunctionTypeVariable oldVariable = variables[i];
      FunctionTypeVariable newVariable = newVariables[i];
      if (identical(oldVariable, newVariable)) continue;
      newVariable.bound = visit(oldVariable.bound, argument);
    }
    return newVariables;
  }

  @override
  DartType visitInterfaceType(covariant InterfaceType type, A argument) {
    List<DartType> typeArguments = type.typeArguments;
    if (typeArguments.isEmpty) {
      // Return fast on non-generic types.
      return type;
    }

    DartType probe = _map[type];
    if (probe != null) return probe;

    List<DartType> newTypeArguments = _substTypes(typeArguments, argument);
    // Create a new type only if necessary.
    if (identical(typeArguments, newTypeArguments)) {
      return _mapped(type, type);
    }
    return _mapped(
        type, dartTypes.interfaceType(type.element, newTypeArguments));
  }

  @override
  DartType visitDynamicType(covariant DynamicType type, A argument) => type;

  @override
  DartType visitErasedType(covariant ErasedType type, A argument) => type;

  @override
  DartType visitAnyType(covariant AnyType type, A argument) => type;

  @override
  DartType visitFutureOrType(covariant FutureOrType type, A argument) {
    DartType probe = _map[type];
    if (probe != null) return probe;

    DartType newTypeArgument = visit(type.typeArgument, argument);
    // Create a new type only if necessary.
    if (identical(type.typeArgument, newTypeArgument)) {
      return _mapped(type, type);
    }
    return _mapped(type, dartTypes.futureOrType(newTypeArgument));
  }

  List<DartType> _substTypes(List<DartType> types, A argument) {
    List<DartType> result;
    for (int i = 0; i < types.length; i++) {
      DartType oldType = types[i];
      DartType newType = visit(oldType, argument);
      if (!identical(newType, oldType)) {
        result ??= types.sublist(0, i);
      }
      result?.add(newType);
    }
    return result ?? types;
  }
}

class _DependencyCheck<A> extends DartTypeStructuralPredicateVisitor {
  final DartTypeSubstitutionVisitor<A> _substitutionVisitor;
  final A argument;

  _DependencyCheck(this._substitutionVisitor, this.argument);

  @override
  bool handleTypeVariableType(TypeVariableType type) {
    return !identical(type,
        _substitutionVisitor.substituteTypeVariableType(type, argument, false));
  }

  @override
  bool handleFreeFunctionTypeVariable(FunctionTypeVariable type) {
    // Function type variables are added to the map for type variables that need
    // to be replaced with updated bounds.
    DartType probe = _substitutionVisitor._map[type];
    if (probe != null) return probe != type;
    return !identical(
        type,
        _substitutionVisitor.substituteFunctionTypeVariable(
            type, argument, false));
  }
}

/// A visitor that by default visits the substructure of the type until some
/// visit returns `true`.  The default handlers return `false` which will search
/// the whole structure unless overridden.
abstract class DartTypeStructuralPredicateVisitor
    extends DartTypeVisitor<bool, List<FunctionTypeVariable>> {
  const DartTypeStructuralPredicateVisitor();

  bool run(DartType type) => visit(type, null);

  bool handleLegacyType(LegacyType type) => false;
  bool handleNullableType(NullableType type) => false;
  bool handleNeverType(NeverType type) => false;
  bool handleVoidType(VoidType type) => false;
  bool handleTypeVariableType(TypeVariableType type) => false;
  bool handleBoundFunctionTypeVariable(FunctionTypeVariable type) => false;
  bool handleFreeFunctionTypeVariable(FunctionTypeVariable type) => false;
  bool handleFunctionType(FunctionType type) => false;
  bool handleInterfaceType(InterfaceType type) => false;
  bool handleDynamicType(DynamicType type) => false;
  bool handleErasedType(ErasedType type) => false;
  bool handleAnyType(AnyType type) => false;
  bool handleFutureOrType(FutureOrType type) => false;

  @override
  bool visitLegacyType(LegacyType type, List<FunctionTypeVariable> bindings) =>
      handleLegacyType(type) || visit(type.baseType, bindings);

  @override
  bool visitNullableType(
          NullableType type, List<FunctionTypeVariable> bindings) =>
      handleNullableType(type) || visit(type.baseType, bindings);

  @override
  bool visitNeverType(NeverType type, List<FunctionTypeVariable> bindings) =>
      false;

  @override
  bool visitVoidType(VoidType type, List<FunctionTypeVariable> bindings) =>
      handleVoidType(type);

  @override
  bool visitTypeVariableType(
          TypeVariableType type, List<FunctionTypeVariable> bindings) =>
      handleTypeVariableType(type);

  @override
  bool visitFunctionTypeVariable(
      FunctionTypeVariable type, List<FunctionTypeVariable> bindings) {
    return bindings != null && bindings.indexOf(type) >= 0
        ? handleBoundFunctionTypeVariable(type)
        : handleFreeFunctionTypeVariable(type);
  }

  @override
  bool visitFunctionType(
      FunctionType type, List<FunctionTypeVariable> bindings) {
    if (handleFunctionType(type)) return true;
    List<FunctionTypeVariable> typeVariables = type.typeVariables;
    if (typeVariables.isNotEmpty) {
      bindings ??= <FunctionTypeVariable>[];
      bindings.addAll(typeVariables);
    }

    bool result = visit(type.returnType, bindings);
    result = result ||
        _visitAll(type.typeVariables.map((variable) => variable.bound).toList(),
            bindings);
    result = result || _visitAll(type.parameterTypes, bindings);
    result = result || _visitAll(type.optionalParameterTypes, bindings);
    result = result || _visitAll(type.namedParameterTypes, bindings);

    bindings?.length -= typeVariables.length;
    return result;
  }

  @override
  bool visitInterfaceType(
      InterfaceType type, List<FunctionTypeVariable> bindings) {
    if (handleInterfaceType(type)) return true;
    return _visitAll(type.typeArguments, bindings);
  }

  @override
  bool visitDynamicType(
          DynamicType type, List<FunctionTypeVariable> bindings) =>
      handleDynamicType(type);

  @override
  bool visitErasedType(ErasedType type, List<FunctionTypeVariable> bindings) =>
      handleErasedType(type);

  @override
  bool visitAnyType(AnyType type, List<FunctionTypeVariable> bindings) =>
      handleAnyType(type);

  @override
  bool visitFutureOrType(
      FutureOrType type, List<FunctionTypeVariable> bindings) {
    if (handleFutureOrType(type)) return true;
    return visit(type.typeArgument, bindings);
  }

  bool _visitAll(List<DartType> types, List<FunctionTypeVariable> bindings) {
    for (DartType type in types) {
      if (visit(type, bindings)) return true;
    }
    return false;
  }
}

class _ContainsFreeTypeVariablesVisitor
    extends DartTypeStructuralPredicateVisitor {
  @override
  bool handleTypeVariableType(TypeVariableType type) => true;

  @override
  bool handleFreeFunctionTypeVariable(FunctionTypeVariable type) => true;
}

class SimpleDartTypeSubstitutionVisitor
    extends DartTypeSubstitutionVisitor<Null> {
  @override
  final DartTypes dartTypes;
  final List<DartType> arguments;
  final List<DartType> parameters;

  SimpleDartTypeSubstitutionVisitor(
      this.dartTypes, this.arguments, this.parameters);

  DartType substitute(DartType input) => visit(input, null);

  @override
  DartType substituteTypeVariableType(
      TypeVariableType type, Null _, bool freshReference) {
    int index = parameters.indexOf(type);
    if (index != -1) {
      return arguments[index];
    }
    // The type variable was not substituted.
    return type;
  }

  @override
  DartType substituteFunctionTypeVariable(
      covariant FunctionTypeVariable type, Null _, bool freshReference) {
    int index = parameters.indexOf(type);
    if (index != -1) {
      return arguments[index];
    }
    // The type variable was not substituted.
    return type;
  }
}

class _DeferredName {
  String name;
  _DeferredName();
  @override
  String toString() => name;
}

class _DartTypeToStringVisitor extends DartTypeVisitor<void, void> {
  final DartTypes _dartTypes; // May be null.
  final CompilerOptions _options; // May be null.
  final List _fragments = []; // Strings and _DeferredNames
  bool _lastIsIdentifier = false;
  List<FunctionTypeVariable> _boundVariables;
  Map<FunctionTypeVariable, _DeferredName> _variableToName;
  Set<FunctionType> _genericFunctions;

  _DartTypeToStringVisitor(this._dartTypes, this._options);

  String run(DartType type) {
    _visit(type);
    if (_variableToName != null &&
        _variableToName.values.any((deferred) => deferred.name == null)) {
      // Assign names to _DeferredNames that were not assigned while visiting a
      // generic function type.
      Set<String> usedNames =
          _variableToName.values.map((deferred) => deferred.name).toSet();
      int startGroup = (_genericFunctions?.length ?? 0) + 1;
      for (var entry in _variableToName.entries) {
        if (entry.value.name != null) continue;
        for (int group = startGroup;; group++) {
          String name = _functionTypeVariableName(entry.key, group);
          if (!usedNames.add(name)) continue;
          entry.value.name = name;
          break;
        }
      }
    }
    return _fragments.join();
  }

  String _functionTypeVariableName(FunctionTypeVariable variable, int group) {
    String prefix = String.fromCharCode(0x41 + variable.index);
    String suffix = group == 1 ? '' : '$group';
    return prefix + suffix;
  }

  void _identifier(String text) {
    if (_lastIsIdentifier) _fragments.add(' ');
    _fragments.add(text);
    _lastIsIdentifier = true;
  }

  void _deferredNameIdentifier(_DeferredName name) {
    if (_lastIsIdentifier) _fragments.add(' ');
    _fragments.add(name);
    _lastIsIdentifier = true;
  }

  void _token(String text) {
    _fragments.add(text);
    _lastIsIdentifier = false;
  }

  bool _comma(bool needsComma) {
    if (needsComma) _token(',');
    return true;
  }

  void _visit(DartType type) {
    type.accept(this, null);
  }

  @override
  void visitLegacyType(covariant LegacyType type, _) {
    _visit(type.baseType);
    // We do not emit the '*' token for legacy types because this is a purely
    // internal notion. The language specification does not define a '*' token
    // in the type language, and no such token should be surfaced to users.
    // For debugging, pass `--debug-print-legacy-stars` to emit the '*'.
    if (_options == null || _options.printLegacyStars) {
      _token('*');
    }
  }

  @override
  void visitNullableType(covariant NullableType type, _) {
    _visit(type.baseType);
    _token('?');
  }

  @override
  void visitNeverType(covariant NeverType type, _) {
    _identifier('Never');
  }

  @override
  void visitVoidType(covariant VoidType type, _) {
    _identifier('void');
  }

  @override
  void visitDynamicType(covariant DynamicType type, _) {
    _identifier('dynamic');
  }

  @override
  void visitErasedType(covariant ErasedType type, _) {
    _identifier('erased');
  }

  @override
  void visitAnyType(covariant AnyType type, _) {
    _identifier('any');
  }

  @override
  void visitTypeVariableType(covariant TypeVariableType type, _) {
    _identifier(type.element.typeDeclaration.name);
    _token('.');
    _identifier(type.element.name);
  }

  _DeferredName _nameFor(FunctionTypeVariable type) {
    _variableToName ??= Map.identity();
    return _variableToName[type] ??= _DeferredName();
  }

  @override
  void visitFunctionTypeVariable(covariant FunctionTypeVariable type, _) {
    // The first letter of the variable name indicates the 'index'.  Names have
    // suffixes corresponding to the different generic function types (A, A2,
    // A3, etc).
    _token('#');
    _deferredNameIdentifier(_nameFor(type));
    if (_boundVariables == null || !_boundVariables.contains(type)) {
      _token('/*free*/');
    }
  }

  @override
  void visitFunctionType(covariant FunctionType type, _) {
    if (type.typeVariables.isNotEmpty) {
      // Enter function type variable scope.
      _boundVariables ??= [];
      _boundVariables.addAll(type.typeVariables);
      // Assign names for the function type variables. We could have already
      // assigned names for this node if we are printing a DAG.
      _genericFunctions ??= Set.identity();
      if (_genericFunctions.add(type)) {
        int group = _genericFunctions.length;
        for (FunctionTypeVariable variable in type.typeVariables) {
          _DeferredName deferredName = _nameFor(variable);
          // If there is a structural error where one FunctionTypeVariable is
          // used in two [FunctionType]s it might already have a name.
          deferredName.name ??= _functionTypeVariableName(variable, group);
        }
      }
    }
    _visit(type.returnType);
    _token(' ');
    _identifier('Function');
    if (type.typeVariables.isNotEmpty) {
      _token('<');
      bool needsComma = false;
      for (FunctionTypeVariable typeVariable in type.typeVariables) {
        needsComma = _comma(needsComma);
        _visit(typeVariable);
        DartType bound = typeVariable.bound;
        if (_dartTypes == null || !_dartTypes.isTopType(bound)) {
          _token(' extends ');
          _visit(bound);
        }
      }
      _token('>');
    }
    _token('(');
    bool needsComma = false;
    for (DartType parameterType in type.parameterTypes) {
      needsComma = _comma(needsComma);
      _visit(parameterType);
    }
    if (type.optionalParameterTypes.isNotEmpty) {
      needsComma = _comma(needsComma);
      _token('[');
      bool needsOptionalComma = false;
      for (DartType typeArgument in type.optionalParameterTypes) {
        needsOptionalComma = _comma(needsOptionalComma);
        _visit(typeArgument);
      }
      _token(']');
    }
    if (type.namedParameters.isNotEmpty) {
      needsComma = _comma(needsComma);
      _token('{');
      bool needsNamedComma = false;
      for (int index = 0; index < type.namedParameters.length; index++) {
        needsNamedComma = _comma(needsNamedComma);
        _visit(type.namedParameterTypes[index]);
        _token(' ');
        _identifier(type.namedParameters[index]);
      }
      _token('}');
    }
    _token(')');
    // Exit function type variable scope.
    _boundVariables?.length -= type.typeVariables.length;
  }

  @override
  void visitInterfaceType(covariant InterfaceType type, _) {
    _identifier(type.element.name);
    _optionalTypeArguments(type.typeArguments);
  }

  void _optionalTypeArguments(List<DartType> types) {
    if (types.isNotEmpty) {
      _token('<');
      bool needsComma = false;
      for (DartType typeArgument in types) {
        needsComma = _comma(needsComma);
        _visit(typeArgument);
      }
      _token('>');
    }
  }

  @override
  void visitFutureOrType(covariant FutureOrType type, _) {
    _identifier('FutureOr');
    _token('<');
    _visit(type.typeArgument);
    _token('>');
  }
}

/// Basic interface for the Dart type system.
abstract class DartTypes {
  /// The types defined in 'dart:core'.
  CommonElements get commonElements;

  bool get useLegacySubtyping;

  DartType bottomType() =>
      useLegacySubtyping ? commonElements.nullType : neverType();

  DartType legacyType(DartType baseType) {
    DartType result;
    if (isStrongTopType(baseType) ||
        baseType.isNull ||
        baseType is LegacyType ||
        baseType is NullableType) {
      result = baseType;
    } else {
      result = LegacyType._(baseType);
    }
    return result;
  }

  DartType nullableType(DartType baseType) {
    bool _isNullable(DartType t) =>
        // Note that we can assume NNBD is enabled here.
        t.isNull ||
        t is NullableType ||
        t is LegacyType && _isNullable(t.baseType) ||
        t is FutureOrType && _isNullable(t.typeArgument) ||
        isStrongTopType(t);

    DartType result;
    if (isStrongTopType(baseType) ||
        baseType.isNull ||
        baseType is NullableType ||
        baseType is FutureOrType && _isNullable(baseType.typeArgument)) {
      result = baseType;
    } else if (baseType is NeverType) {
      result = commonElements.nullType;
    } else if (baseType is LegacyType) {
      DartType legacyBaseType = baseType.baseType;
      if (legacyBaseType is NeverType) {
        result = commonElements.nullType;
      } else if (legacyBaseType is FutureOrType &&
          _isNullable(legacyBaseType.typeArgument)) {
        result = legacyBaseType;
      } else {
        result = nullableType(legacyBaseType);
      }
    } else {
      result = NullableType._(baseType);
    }
    return result;
  }

  InterfaceType interfaceType(
          ClassEntity element, List<DartType> typeArguments) =>
      InterfaceType._(element, typeArguments);

  // TODO(fishythefish): Normalize `T extends Never` to `Never`.
  TypeVariableType typeVariableType(TypeVariableEntity element) =>
      TypeVariableType._(element);

  // See [functionType] for normalization.
  FunctionTypeVariable functionTypeVariable(int index) =>
      FunctionTypeVariable._(index);

  NeverType neverType() => const NeverType._();

  VoidType voidType() => const VoidType._();

  DynamicType dynamicType() => const DynamicType._();

  ErasedType erasedType() => const ErasedType._();

  AnyType anyType() => const AnyType._();

  FunctionType functionType(
      DartType returnType,
      List<DartType> parameterTypes,
      List<DartType> optionalParameterTypes,
      List<String> namedParameters,
      Set<String> requiredNamedParameters,
      List<DartType> namedParameterTypes,
      List<FunctionTypeVariable> typeVariables) {
    FunctionType type = FunctionType._(
        returnType,
        parameterTypes,
        optionalParameterTypes,
        namedParameters,
        requiredNamedParameters,
        namedParameterTypes,
        typeVariables);
    List<FunctionTypeVariable> normalizableVariables = typeVariables
        .where((FunctionTypeVariable t) => t.bound is NeverType)
        .toList();
    return normalizableVariables.isEmpty
        ? type
        : subst(
            List<DartType>.filled(normalizableVariables.length, neverType()),
            normalizableVariables,
            type);
  }

  DartType futureOrType(DartType typeArgument) {
    DartType result;
    if (isTopType(typeArgument) || typeArgument.isObject) {
      result = typeArgument;
    } else if (typeArgument is NeverType) {
      result = commonElements.futureType(typeArgument);
    } else if (typeArgument.isNull) {
      DartType futureOfNull =
          commonElements.futureType(commonElements.nullType);
      result = nullableType(futureOfNull);
    } else {
      result = FutureOrType._(typeArgument);
    }
    return result;
  }

  DartType eraseLegacy(DartType type) =>
      _LegacyErasureVisitor(this).erase(type);

  /// Performs the substitution `[arguments[i]/parameters[i]]t`.
  ///
  /// The notation is known from this lambda calculus rule:
  ///
  ///     (lambda x.e0)e1 -> [e1/x]e0.
  ///
  /// See [TypeVariableType] for a motivation for this method.
  ///
  /// Invariant: There must be the same number of [arguments] and [parameters].
  DartType subst(
      List<DartType> arguments, List<DartType> parameters, DartType t) {
    assert(arguments.length == parameters.length);
    if (parameters.isEmpty) return t;
    return SimpleDartTypeSubstitutionVisitor(this, arguments, parameters)
        .substitute(t);
  }

  DartType instantiate(FunctionType t, List<DartType> arguments) {
    assert(arguments.length == t.typeVariables.length,
        'Generic function type instantiation is all-or-none');
    DartType _subst(DartType type) => subst(arguments, t.typeVariables, type);
    DartType returnType = _subst(t.returnType);
    List<DartType> parameterTypes = t.parameterTypes.map(_subst).toList();
    List<DartType> optionalParameterTypes =
        t.optionalParameterTypes.map(_subst).toList();
    List<DartType> namedParameterTypes =
        t.namedParameterTypes.map(_subst).toList();
    return functionType(
        returnType,
        parameterTypes,
        optionalParameterTypes,
        t.namedParameters,
        t.requiredNamedParameters,
        namedParameterTypes, const []);
  }

  /// Returns `true` if every type argument of [t] is a top type.
  // TODO(fishythefish): Should we instead check if each type argument is at its
  // bound?
  bool treatAsRawType(DartType t) {
    t = t.withoutNullability;
    if (t is InterfaceType) {
      for (DartType type in t.typeArguments) {
        if (!isTopType(type)) return false;
      }
    }
    return true;
  }

  /// Returns `true` if [t] is a bottom type, that is, a subtype of every type.
  bool isBottomType(DartType t) =>
      t is NeverType || (useLegacySubtyping && t.isNull);

  /// Returns `true` if [t] is a top type, that is, a supertype of every type.
  bool isTopType(DartType t) =>
      isStrongTopType(t) ||
      t is LegacyType && t.baseType.isObject ||
      useLegacySubtyping && t.isObject;

  bool isStrongTopType(DartType t) =>
      t is VoidType ||
      t is DynamicType ||
      t is ErasedType ||
      t is AnyType ||
      t is NullableType && t.baseType.isObject;

  /// Returns `true` if [s] is a subtype of [t].
  bool isSubtype(DartType s, DartType t) => _subtypeHelper(s, t);

  /// Returns `true` if [s] is assignable to [t].
  bool isAssignable(DartType s, DartType t) =>
      isSubtype(s, t) || isSubtype(t, s);

  /// Returns `true` if [s] might be a subtype of [t] for some values of
  /// type variables in [s] and [t].
  ///
  /// If [assumeInstantiations], generic function types are assumed to be
  /// potentially instantiated.
  bool isPotentialSubtype(DartType s, DartType t,
          {bool assumeInstantiations: true}) =>
      _subtypeHelper(s, t,
          allowPotentialSubtypes: true,
          assumeInstantiations: assumeInstantiations);

  bool _subtypeHelper(DartType s, DartType t,
      {bool allowPotentialSubtypes: false, bool assumeInstantiations: false}) {
    assert(allowPotentialSubtypes || !assumeInstantiations);

    // TODO(fishythefish): Add constraint solving for potential subtypes.
    if (allowPotentialSubtypes) return true;

    /// Based on
    /// https://github.com/dart-lang/language/blob/master/resources/type-system/subtyping.md.
    /// See also [_isSubtype] in `dart:_rti`.
    bool _isSubtype(DartType s, DartType t, _Assumptions env) {
      // Reflexivity:
      if (s == t) return true;
      if (env != null &&
          s is FunctionTypeVariable &&
          t is FunctionTypeVariable &&
          env.isAssumed(s, t)) return true;

      if (s is AnyType) return true;

      // Right Top:
      if (isTopType(t)) return true;

      // Left Top:
      if (isStrongTopType(s)) return false;

      // Left Bottom:
      if (isBottomType(s)) return true;

      // Left Type Variable Bound 1:
      if (s is TypeVariableType) {
        if (_isSubtype(getTypeVariableBound(s.element), t, env)) return true;
      }
      if (s is FunctionTypeVariable) {
        if (_isSubtype(s._bound, t, env)) return true;
      }

      // Left Null:
      // Note: Interchanging the Left Null and Right Object rules allows us to
      // reduce casework.
      if (!useLegacySubtyping && s.isNull) {
        if (t is FutureOrType) {
          return _isSubtype(s, t.typeArgument, env);
        }
        return t.isNull || t is LegacyType || t is NullableType;
      }

      // Right Object:
      if (!useLegacySubtyping && t.isObject) {
        if (s is FutureOrType) {
          return _isSubtype(s.typeArgument, t, env);
        }
        if (s is LegacyType) {
          return _isSubtype(s.baseType, t, env);
        }
        return s is! NullableType;
      }

      // Left Legacy:
      if (s is LegacyType) {
        return _isSubtype(s.baseType, t, env);
      }

      // Right Legacy:
      if (t is LegacyType) {
        // Note that to convert `T*` to `T?`, we can't just say `t._toNullable`.
        // The resulting type `T?` may be normalizable (e.g. if `T` is `Never`).
        return _isSubtype(
            s, useLegacySubtyping ? t.baseType : nullableType(t), env);
      }

      // Left FutureOr:
      if (s is FutureOrType) {
        DartType typeArgument = s.typeArgument;
        return _isSubtype(typeArgument, t, env) &&
            _isSubtype(commonElements.futureType(typeArgument), t, env);
      }

      // Left Nullable:
      if (s is NullableType) {
        return (useLegacySubtyping ||
                _isSubtype(commonElements.nullType, t, env)) &&
            _isSubtype(s.baseType, t, env);
      }

      // Type Variable Reflexivity 1 is subsumed by Reflexivity and therefore
      // elided.
      // Type Variable Reflexivity 2 does not apply because we do not represent
      // promoted type variables.
      // Right Promoted Variable does not apply because we do not represent
      // promoted type variables.

      // Right FutureOr:
      if (t is FutureOrType) {
        DartType typeArgument = t.typeArgument;
        return _isSubtype(s, typeArgument, env) ||
            _isSubtype(s, commonElements.futureType(typeArgument), env);
      }

      // Right Nullable:
      if (t is NullableType) {
        return (!useLegacySubtyping &&
                _isSubtype(s, commonElements.nullType, env)) ||
            _isSubtype(s, t.baseType, env);
      }

      // Left Promoted Variable does not apply because we do not represent
      // promoted type variables.

      // Left Type Variable Bound 2:
      if (s is TypeVariableType) return false;
      if (s is FunctionTypeVariable) return false;

      // Function Type/Function:
      if (s is FunctionType && t == commonElements.functionType) {
        return true;
      }

      // Positional Function Types + Named Function Types:
      // TODO(fishythefish): Disallow JavaScriptFunction as a subtype of
      // function types using features inaccessible from JavaScript.
      if (t is FunctionType) {
        if (s == commonElements.jsJavaScriptFunctionType) return true;
        if (s is FunctionType) {
          List<FunctionTypeVariable> sTypeVariables = s.typeVariables;
          List<FunctionTypeVariable> tTypeVariables = t.typeVariables;
          int length = tTypeVariables.length;
          if (length != sTypeVariables.length) return false;

          env ??= _Assumptions();
          env.assumePairs(sTypeVariables, tTypeVariables);
          try {
            for (int i = 0; i < length; i++) {
              DartType sBound = sTypeVariables[i].bound;
              DartType tBound = tTypeVariables[i].bound;
              if (!_isSubtype(sBound, tBound, env) ||
                  !_isSubtype(tBound, sBound, env)) {
                return false;
              }
            }

            if (!_isSubtype(s.returnType, t.returnType, env)) return false;

            List<DartType> sRequiredPositional = s.parameterTypes;
            List<DartType> tRequiredPositional = t.parameterTypes;
            int sRequiredPositionalLength = sRequiredPositional.length;
            int tRequiredPositionalLength = tRequiredPositional.length;
            if (sRequiredPositionalLength > tRequiredPositionalLength) {
              return false;
            }
            int requiredPositionalDelta =
                tRequiredPositionalLength - sRequiredPositionalLength;

            List<DartType> sOptionalPositional = s.optionalParameterTypes;
            List<DartType> tOptionalPositional = t.optionalParameterTypes;
            int sOptionalPositionalLength = sOptionalPositional.length;
            int tOptionalPositionalLength = tOptionalPositional.length;
            if (sRequiredPositionalLength + sOptionalPositionalLength <
                tRequiredPositionalLength + tOptionalPositionalLength) {
              return false;
            }

            for (int i = 0; i < sRequiredPositionalLength; i++) {
              if (!_isSubtype(
                  tRequiredPositional[i], sRequiredPositional[i], env)) {
                return false;
              }
            }

            for (int i = 0; i < requiredPositionalDelta; i++) {
              if (!_isSubtype(
                  tRequiredPositional[sRequiredPositionalLength + i],
                  sOptionalPositional[i],
                  env)) {
                return false;
              }
            }

            for (int i = 0; i < tOptionalPositionalLength; i++) {
              if (!_isSubtype(tOptionalPositional[i],
                  sOptionalPositional[requiredPositionalDelta + i], env)) {
                return false;
              }
            }

            List<String> sNamed = s.namedParameters;
            List<String> tNamed = t.namedParameters;
            Set<String> sRequiredNamed = s.requiredNamedParameters;
            Set<String> tRequiredNamed = t.requiredNamedParameters;
            List<DartType> sNamedTypes = s.namedParameterTypes;
            List<DartType> tNamedTypes = t.namedParameterTypes;
            int sNamedLength = sNamed.length;
            int tNamedLength = tNamed.length;

            int sIndex = 0;
            for (int tIndex = 0; tIndex < tNamedLength; tIndex++) {
              String tName = tNamed[tIndex];
              while (true) {
                if (sIndex >= sNamedLength) return false;
                String sName = sNamed[sIndex++];
                int comparison = sName.compareTo(tName);
                if (comparison > 0) return false;
                bool sIsRequired =
                    !useLegacySubtyping && sRequiredNamed.contains(sName);
                if (comparison < 0) {
                  if (sIsRequired) return false;
                  continue;
                }
                bool tIsRequired =
                    !useLegacySubtyping && tRequiredNamed.contains(tName);
                if (sIsRequired && !tIsRequired) return false;
                if (!_isSubtype(
                    tNamedTypes[tIndex], sNamedTypes[sIndex - 1], env))
                  return false;
                break;
              }
            }
            if (!useLegacySubtyping) {
              while (sIndex < sNamedLength) {
                if (sRequiredNamed.contains(sNamed[sIndex++])) return false;
              }
            }
            return true;
          } finally {
            if (length > 0) env.forgetPairs(sTypeVariables, tTypeVariables);
          }
        }
        return false;
      }

      // Interface Compositionality + Super-Interface:
      if (s is InterfaceType) {
        if (t is InterfaceType) {
          InterfaceType instance =
              s.element == t.element ? s : asInstanceOf(s, t.element);
          if (instance == null) return false;
          List<DartType> sArgs = instance.typeArguments;
          List<DartType> tArgs = t.typeArguments;
          List<Variance> variances = getTypeVariableVariances(t.element);
          assert(sArgs.length == tArgs.length);
          assert(tArgs.length == variances.length);
          for (int i = 0; i < variances.length; i++) {
            switch (variances[i]) {
              case Variance.legacyCovariant:
              case Variance.covariant:
                if (!_isSubtype(sArgs[i], tArgs[i], env)) return false;
                break;
              case Variance.contravariant:
                if (!_isSubtype(tArgs[i], sArgs[i], env)) return false;
                break;
              case Variance.invariant:
                if (!_isSubtype(sArgs[i], tArgs[i], env) ||
                    !_isSubtype(tArgs[i], sArgs[i], env)) return false;
                break;
              default:
                throw StateError(
                    "Invalid variance ${variances[i]} used for subtype check.");
            }
          }
          return true;
        }
        return false;
      }

      return false;
    }

    return _isSubtype(s, t, null);
  }

  /// Returns [type] as an instance of [cls] or `null` if [type] is not a
  /// subtype of [cls].
  ///
  /// For example: `asInstanceOf(List<String>, Iterable) = Iterable<String>`.
  InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls);

  /// Return [base] where the type variable of `context.element` are replaced
  /// by the type arguments of [context].
  ///
  /// For instance
  ///
  ///     substByContext(Iterable<List.E>, List<String>) = Iterable<String>
  ///
  DartType substByContext(DartType base, InterfaceType context);

  /// Returns the 'this type' of [cls]. That is, the instantiation of [cls]
  /// where the type arguments are the type variables of [cls].
  InterfaceType getThisType(ClassEntity cls);

  /// Returns the supertype of [cls], i.e. the type in the `extends` clause of
  /// [cls].
  InterfaceType getSupertype(ClassEntity cls);

  /// Returns all supertypes of [cls].
  // TODO(johnniwinther): This should include `Function` if [cls] declares
  // a `call` method.
  Iterable<InterfaceType> getSupertypes(ClassEntity cls);

  /// Returns all types directly implemented by [cls].
  Iterable<InterfaceType> getInterfaces(ClassEntity cls);

  /// Returns the type of the `call` method on [type], or `null` if the class
  /// of [type] does not have a `call` method.
  FunctionType getCallType(InterfaceType type);

  /// Checks the type arguments of [type] against the type variable bounds
  /// declared on `type.element`. Calls [checkTypeVariableBound] on each type
  /// argument and bound.
  void checkTypeVariableBounds<T>(
      T context,
      List<DartType> typeArguments,
      List<DartType> typeVariables,
      void checkTypeVariableBound(T context, DartType typeArgument,
          TypeVariableType typeVariable, DartType bound));

  /// Returns the [ClassEntity] which declares the type variables occurring in
  // [type], or `null` if [type] does not contain class type variables.
  static ClassEntity getClassContext(DartType type) {
    ClassEntity contextClass;
    type.forEachTypeVariable((TypeVariableType typeVariable) {
      if (typeVariable.element.typeDeclaration is! ClassEntity) return;
      contextClass = typeVariable.element.typeDeclaration;
    });
    // GENERIC_METHODS: When generic method support is complete enough to
    // include a runtime value for method type variables this must be updated.
    // For full support the global assumption that all type variables are
    // declared by the same enclosing class will not hold: Both an enclosing
    // method and an enclosing class may define type variables, so the return
    // type cannot be [ClassElement] and the caller must be prepared to look in
    // two locations, not one. Currently we ignore method type variables by
    // returning in the next statement.
    return contextClass;
  }

  DartType getTypeVariableBound(TypeVariableEntity element);

  List<Variance> getTypeVariableVariances(ClassEntity cls);

  DartType getTearOffParameterType(
      DartType type, bool isCovariant, bool isNonNullableByDefaultLibrary) {
    if (isCovariant) {
      // A covariant parameter has type `Object` in the method signature.
      var objectType = commonElements.objectType;
      if (isNonNullableByDefaultLibrary) {
        return nullableType(objectType);
      } else {
        return legacyType(objectType);
      }
    }
    return type;
  }

  bool canAssignGenericFunctionTo(DartType type) {
    type = type.withoutNullability;
    return type is FunctionType && type.typeVariables.isNotEmpty ||
        isSubtype(commonElements.functionType, type) ||
        type is FutureOrType && canAssignGenericFunctionTo(type.typeArgument) ||
        type is TypeVariableType &&
            canAssignGenericFunctionTo(getTypeVariableBound(type.element)) ||
        type is FunctionTypeVariable && canAssignGenericFunctionTo(type.bound);
  }

  /// Returns `true` if [type] occuring in a program with no sound null safety
  /// cannot accept `null` under sound rules.
  bool isNonNullableIfSound(DartType type) {
    if (type is DynamicType ||
        type is VoidType ||
        type is AnyType ||
        type is ErasedType) {
      return false;
    }
    if (type is NullableType) return false;
    if (type is LegacyType) {
      return isNonNullableIfSound(type.baseType);
    }
    if (type is InterfaceType) {
      if (type.isNull) return false;
      return true;
    }
    if (type is FunctionType) return true;
    if (type is NeverType) return true;
    if (type is TypeVariableType) {
      return isNonNullableIfSound(getTypeVariableBound(type.element));
    }
    if (type is FutureOrType) {
      return isNonNullableIfSound(type.typeArgument);
    }
    throw UnimplementedError('isNonNullableIfSound $type');
  }
}
