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

// Generates the type tables used by DartFuzz.
//
// Usage:
//   dart gen_type_table.dart > dartfuzz_type_table.dart
//
// Reformat:
//   tools/sdks/dart-sdk/bin/dartfmt -w \
//   runtime/tools/dartfuzz/dartfuzz_type_table.dart
//
// Then send out modified dartfuzz_type_table.dart for review together
// with a modified dartfuzz.dart that increases the version.

import 'dart:io';
import 'dart:math';

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:args/args.dart';

import 'gen_util.dart';

// Minimum number of operators that are required for a type to be included in
// the type table.
final int operatorCountThreshold = 2;

//
// Operators and functions.
//

// Map type to a list of constructors names with a list of constructor
// parameter types.
Map<String, Map<String, List<String>>> constructors =
    <String, Map<String, List<String>>>{};

// Map type to a list of assignment operators with a set of the
// assignable right hand side types.
Map<String, Map<String, Set<String>>> assignOps =
    <String, Map<String, Set<String>>>{};

// Map type to a list of binary operators with set of the respective
// types for the first and second operand.
Map<String, Map<String, Set<List<String>>>> binOps =
    <String, Map<String, Set<List<String>>>>{};

// Map type to a list of available unary operators.
Map<String, Set<String>> uniOps = <String, Set<String>>{};

//
// Type grouping.
//

// All Set<E> types: SET_INT, SET_STRING, etc.
Set<String> setTypes = <String>{};

// All Map<K, V> types: MAP_INT_STRING, MAP_DOUBLE_BOOL, etc.
Set<String> mapTypes = <String>{};

// All List<E> types: LIST_INT, LIST_STRING, etc.
Set<String> listTypes = <String>{};

// All floating point types: DOUBLE, SET_DOUBLE, MAP_X_DOUBLE, etc.
Set<String> fpTypes = <String>{};

// All iterable types: Set types + List types.
// These can be used in for(x in <iterable type>),
// therefore Map is not included.
Set<String> iterableTypes1 = <String>{};

// All trivially indexable types: Map types and List types.
// Elements of these can be written and read by [], unlike Set
// which uses getElementAt to access individual elements
Set<String> indexableTypes = <String>{};

// Complex types: Collection types instantiated with nested argument
// e.g Map<List<>, >.
Set<String> complexTypes = <String>{};

//
// Type relations.
//

// Map type to the resulting type when subscripted.
// Example: List<String> subscripts to String.
Map<String, String> subscriptsTo = <String, String>{};

// Map type to a Set of types that contain it as an element.
// Example: String is element of List<String> and Map<int, String>
Map<String, Set<String>> elementOf = <String, Set<String>>{};

// Map type to a Set of types that contain it as an indexable element.
// Same as element of, but without Set types.
Map<String, Set<String>> indexableElementOf = <String, Set<String>>{};

// Map type to type required as index.
// Example: List<String> is indexed by int,
// Map<String, double> indexed by String.
Map<String, String> indexedBy = <String, String>{};

//
// Interface relationships.
//

// Map Interface type to Set of types that implement it.
// Example: interface num is implemented by int and double.
Map<String, Set<String>> interfaceRels = <String, Set<String>>{};

// Convert analyzer's displayName to constant name used by dartfuzz.
// Example: Set<int, String> -> SET_INT_STRING
String getConstName(String displayName) {
  var constName = displayName;
  constName = constName.replaceAll('<', '_');
  constName = constName.replaceAll('>', '');
  constName = constName.replaceAll(', ', '_');
  constName = constName.toUpperCase();
  return constName;
}

// Returns true if the given type fails the filter criteria.
bool shouldFilterType(String typName, {bool fp = true, bool flatTp = false}) {
  if (!fp && fpTypes.contains(typName)) {
    return true;
  }
  if (flatTp && complexTypes.contains(typName)) {
    return true;
  }
  return false;
}

// Returns true if any of the paramters in the list fails the
// filter criteria.
bool shouldFilterParameterList(List<String> parameters,
    {bool fp = true, bool flatTp = false}) {
  for (var parameter in parameters) {
    if (shouldFilterType(parameter, fp: fp, flatTp: flatTp)) {
      return true;
    }
  }
  return false;
}

// Filter a set of a list of parameters according to their type.
// A paramter list is only retained if all of the contained paramters
// pass the filter criteria.
Set<List<String>> filterParameterList(Set<List<String>> parameterList,
    {bool fp = true, bool flatTp = false}) {
  var filteredParams = <List<String>>{};
  for (var parameters in parameterList) {
    if (!shouldFilterParameterList(parameters, fp: fp, flatTp: flatTp)) {
      filteredParams.add(parameters);
    }
  }
  return filteredParams;
}

// Filter a set of parameters according to their type.
Set<String> filterParameterSet(Set<String> parameterSet,
    {bool fp = true, bool flatTp = false}) {
  var filteredParams = <String>{};
  for (var parameter in parameterSet) {
    if (!shouldFilterType(parameter, fp: fp, flatTp: flatTp)) {
      filteredParams.add(parameter);
    }
  }
  return filteredParams;
}

// Filter map of operators to a set of a list of parameter types
// as used for binary operators.
Map<String, Set<List<String>>> filterOperatorMapSetList(
    Map<String, Set<List<String>>> operators,
    {bool fp = true,
    bool flatTp = false}) {
  var filteredOps = <String, Set<List<String>>>{};
  operators.forEach((op, parameterList) {
    var filteredParams =
        filterParameterList(parameterList, fp: fp, flatTp: flatTp);
    if (filteredParams.isNotEmpty) {
      filteredOps[op] = filteredParams;
    }
  });
  return filteredOps;
}

// Filter map of operators to a List of parameter types as used for
// constructors.
Map<String, List<String>> filterOperatorMapList(
    Map<String, List<String>> operators,
    {bool fp = true,
    bool flatTp = false}) {
  var filteredOps = <String, List<String>>{};
  operators.forEach((op, parameterList) {
    if (!shouldFilterParameterList(parameterList, fp: fp, flatTp: flatTp)) {
      filteredOps[op] = parameterList;
    }
  });
  return filteredOps;
}

// Filter map of operators to a set of rhs types as used for assignment
// operators.
Map<String, Set<String>> filterOperatorMapSet(
    Map<String, Set<String>> operators,
    {bool fp = true,
    bool flatTp = false}) {
  var filteredOps = <String, Set<String>>{};
  operators.forEach((op, parameterSet) {
    var filteredParams =
        filterParameterSet(parameterSet, fp: fp, flatTp: flatTp);
    if (filteredParams.isNotEmpty) {
      filteredOps[op] = filteredParams;
    }
  });
  return filteredOps;
}

// Filter map of type to map of operators as used for binary operators.
Map<String, Map<String, Set<List<String>>>> filterTypesMap4(
    Map<String, Map<String, Set<List<String>>>> types,
    {bool fp = true,
    bool flatTp = false}) {
  var filteredTypes = <String, Map<String, Set<List<String>>>>{};
  types.forEach((baseType, ops) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return;
    }
    var filteredOps = filterOperatorMapSetList(ops, fp: fp, flatTp: flatTp);
    if (filteredOps.isNotEmpty) {
      filteredTypes[baseType] = filteredOps;
    }
  });
  return filteredTypes;
}

// Print map of type to map of operators as used for binary operators.
void printTypeMap4(
    String name, Map<String, Map<String, Set<List<String>>>> types,
    {bool fp = true, bool flatTp = false}) {
  final subclass = !fp || flatTp;
  final prefix = "${subclass ? "DartType." : ""}";
  print('  static const Map<DartType, Map<String, '
      'Set<List<DartType>>>> $name = {');
  var filteredTypes = filterTypesMap4(types, fp: fp, flatTp: flatTp);
  for (var baseType in filteredTypes.keys.toList()..sort()) {
    var ops = filteredTypes[baseType]!;
    print('    $prefix$baseType: {');
    for (var op in ops.keys.toList()..sort()) {
      var paramTypeL = ops[op]!;
      print("      '$op': {");
      for (var paramTypes in paramTypeL) {
        stdout.write('          [');
        for (var paramType in paramTypes) {
          stdout.write('$prefix$paramType, ');
        }
        print('],');
      }
      print('        },');
    }
    print('    },');
  }
  print('  };');
}

// Filter map of type to map of operators as used for assignment operators.
Map<String, Map<String, Set<String>>> filterTypesMap3Set(
    Map<String, Map<String, Set<String>>> types,
    {bool fp = true,
    bool flatTp = false}) {
  var filteredTypes = <String, Map<String, Set<String>>>{};
  types.forEach((baseType, ops) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return;
    }
    var filteredOps = filterOperatorMapSet(ops, fp: fp, flatTp: flatTp);
    if (filteredOps.isNotEmpty) {
      filteredTypes[baseType] = filteredOps;
    }
  });
  return filteredTypes;
}

// Print map of type to map of operators as used for assignment operators.
void printTypeMap3Set(String name, Map<String, Map<String, Set<String>>> types,
    {bool fp = true, bool flatTp = false}) {
  final subclass = !fp || flatTp;
  final prefix = "${subclass ? "DartType." : ""}";
  print(
      '  static const Map<DartType, ' 'Map<String, Set<DartType>>> $name = {');

  var filteredTypes = filterTypesMap3Set(types, fp: fp, flatTp: flatTp);
  for (var baseType in filteredTypes.keys.toList()..sort()) {
    var ops = filteredTypes[baseType]!;
    print('    $prefix$baseType: {');
    for (var op in ops.keys.toList()) {
      var paramTypes = ops[op]!;
      stdout.write("      '$op': {");
      for (var paramType in paramTypes.toList()..sort()) {
        stdout.write('$prefix$paramType, ');
      }
      print('}, ');
    }
    print('    },');
  }
  print('  };');
}

// Filter map of type to map of operators as used for constructors.
Map<String, Map<String, List<String>>> filterTypesMap3(
    Map<String, Map<String, List<String>>> types,
    {bool fp = true,
    bool flatTp = false}) {
  var filteredTypes = <String, Map<String, List<String>>>{};
  types.forEach((baseType, ops) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return;
    }
    var filteredOps = filterOperatorMapList(ops, fp: fp, flatTp: flatTp);
    if (filteredOps.isNotEmpty) {
      filteredTypes[baseType] = filteredOps;
    }
  });
  return filteredTypes;
}

// Print map of type to map of operators as used for constructors.
void printTypeMap3(String name, Map<String, Map<String, List<String>>> types,
    {bool fp = true, bool flatTp = false}) {
  final subclass = !fp || flatTp;
  final prefix = "${subclass ? "DartType." : ""}";
  print(
      '  static const Map<DartType, Map<String, ' 'List<DartType>>> $name = {');
  var filteredTypes = filterTypesMap3(types, fp: fp, flatTp: flatTp);
  for (var baseType in filteredTypes.keys.toList()..sort()) {
    var ops = filteredTypes[baseType]!;
    print('    $prefix$baseType: {');
    for (var op in ops.keys.toList()..sort()) {
      var paramTypes = ops[op]!;
      stdout.write("      '$op': [");
      for (var paramType in paramTypes.toList()) {
        stdout.write('$prefix$paramType, ');
      }
      print('], ');
    }
    print('    },');
  }
  print('  };');
}

// Filter map of type collection name to set of types.
Map<String, Set<String>> filterTypesMap2(Map<String, Set<String>> types,
    {bool fp = true, bool flatTp = false}) {
  var filteredTypes = <String, Set<String>>{};
  types.forEach((baseType, parameterSet) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return;
    }
    var filteredParams =
        filterParameterSet(parameterSet, fp: fp, flatTp: flatTp);
    if (filteredParams.isNotEmpty) {
      filteredTypes[baseType] = filteredParams;
    }
  });
  return filteredTypes;
}

// Print map of type collection name to set of types.
void printTypeMap2(String name, Map<String, Set<String>> types,
    {bool fp = true, bool flatTp = false}) {
  final subclass = !fp || flatTp;
  final prefix = "${subclass ? "DartType." : ""}";
  print('  static const Map<DartType, Set<DartType>> $name = {');
  var filteredTypes = filterTypesMap2(types, fp: fp, flatTp: flatTp);
  for (var baseType in filteredTypes.keys.toList()..sort()) {
    var paramTypes = filteredTypes[baseType]!;
    stdout.write('    $prefix$baseType: { ');
    for (var paramType in paramTypes.toList()..sort()) {
      stdout.write('$prefix$paramType, ');
    }
    print('},');
  }
  print('  };');
}

// Filter map of type to type.
Map<String, String> filterTypesMap1(Map<String, String> types,
    {bool fp = true, bool flatTp = false}) {
  var filteredTypes = <String, String>{};
  types.forEach((baseType, paramType) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return;
    }
    if (shouldFilterType(paramType, fp: fp, flatTp: flatTp)) {
      return;
    }
    filteredTypes[baseType] = paramType;
  });
  return filteredTypes;
}

// Print map of type to type.
void printTypeMap1(String name, Map<String, String> types,
    {bool fp = true, bool flatTp = false}) {
  final subclass = !fp || flatTp;
  final prefix = "${subclass ? "DartType." : ""}";
  print('  static const Map<DartType, DartType> $name = {');
  var filteredTypes = filterTypesMap1(types, fp: fp, flatTp: flatTp);
  for (var baseType in filteredTypes.keys.toList()..sort()) {
    var paramType = filteredTypes[baseType]!;
    print('    $prefix$baseType: $prefix$paramType, ');
  }
  print('  };');
}

// Filter set of types.
Set<String> filterTypesSet(Set<String> choices,
    {bool fp = true, bool flatTp = false}) {
  var filteredTypes = <String>{};
  filteredTypes.addAll(choices);
  if (!fp) {
    filteredTypes = filteredTypes.difference(fpTypes);
  }
  if (flatTp) {
    filteredTypes = filteredTypes.difference(complexTypes);
  }
  return filteredTypes;
}

// Print set of types.
void printTypeSet(String name, Set<String> types,
    {bool fp = true, bool flatTp = false}) {
  final subclass = !fp || flatTp;
  final prefix = "${subclass ? "DartType." : ""}";
  stdout.write('  static const Set<DartType> $name = {');
  for (var typName in filterTypesSet(types, fp: fp, flatTp: flatTp).toList()
    ..sort()) {
    stdout.write('$prefix$typName, ');
    stdout.write('$prefix${typName}_NULLABLE, ');
  }
  print('};');
}

// Filter map to type to set of operators as used for unitary operators.
Map<String, Set<String>> filterTypeMapSet(Map<String, Set<String>> types,
    {bool fp = true, bool flatTp = false}) {
  var filteredTypes = <String, Set<String>>{};
  types.forEach((baseType, params) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return;
    }
    filteredTypes[baseType] = params;
  });
  return filteredTypes;
}

// Print map to type to set of operators as used for unitary operators.
void printTypeMapSet(String name, Map<String, Set<String>> types,
    {bool fp = true, bool flatTp = false}) {
  final subclass = !fp || flatTp;
  final prefix = "${subclass ? "DartType." : ""}";
  print('  static const Map<DartType, Set<String>> $name = {');
  var filteredTypes = filterTypeMapSet(types, fp: fp, flatTp: flatTp);
  for (var baseType in filteredTypes.keys.toList()..sort()) {
    var paramTypes = filteredTypes[baseType]!.toList()..sort();
    print('    $prefix$baseType: {' + paramTypes.join(', ') + '},');
  }
  print('  };');
}

// Print all generated and collected types, operators and type collections.
void printTypeTable(Set<InterfaceType> allTypes,
    {bool fp = true, bool flatTp = false}) {
  final subclass = !fp || flatTp;
  if (!subclass) {
    print('''
// Copyright (c) 2019, 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.

// ignore_for_file: annotate_overrides
// ignore_for_file: unused_element
// ignore_for_file: unused_field

/// Class that represents some common Dart types.
///
/// NOTE: this code has been generated automatically.
///''');
  }

  var className = 'DartType${fp ? "" : "NoFp"}${flatTp ? "FlatTp" : ""}';

  print('class $className'
      '${subclass ? " extends DartType" : ""} {');
  print('  final String name;');
  print('  final bool isNullable;');
  if (!subclass) {
    print('  const DartType._withName(this.name, this.isNullable);');
    print('''
  factory $className.fromDartConfig(
      {bool enableFp = false, bool disableNesting =
    false}) {
    if (enableFp && !disableNesting) {
      return DartType();
    } else if (!enableFp && !disableNesting) {
      return DartTypeNoFp();
    } else if (enableFp && disableNesting) {
      return DartTypeFlatTp();
    } else {
      return DartTypeNoFpFlatTp();
    }
  }''');
  } else {
    print('  const $className'
        '._withName(this.name, this.isNullable) : super._withName(name, isNullable);');
  }

  print('''
  const $className() : name = "!", isNullable = false;

  String get dartName { return name + (isNullable ? "?" : ""); }
  String toString() { return "DartType(\$dartName)"; }

  static bool isListType(DartType tp) {
    return DartType._listTypes.contains(tp.toNonNullable());
  }

  static bool isSetType(DartType tp) {
    return DartType._setTypes.contains(tp.toNonNullable());
  }

  static bool isMapType(DartType tp) {
    return DartType._mapTypes.contains(tp.toNonNullable());
  }

  static bool isCollectionType(DartType tp) {
    return DartType._collectionTypes.contains(tp.toNonNullable());
  }

  static bool isGrowableType(DartType tp) {
    return DartType._growableTypes.contains(tp.toNonNullable());
  }

  static bool isComplexType(DartType tp) {
    return DartType._complexTypes.contains(tp.toNonNullable());
  }

  DartType toNullable() {
    if (isNullable) {
      return this;
    }
    for (var tp in _allTypes) {
      if (tp.isNullable && tp.name == name) return tp;
    }
    throw 'Fail toNullable \$name \$isNullable';
  }

  DartType toNonNullable() {
    if (!isNullable) {
      return this;
    }
    for (var tp in _allTypes) {
      if (!tp.isNullable && tp.name == name) return tp;
    }
    throw 'Fail toNonNullable \$name \$isNullable';
  }

  bool isInterfaceOfType(DartType tp, DartType iTp) {
    tp = tp.toNonNullable();
    iTp = iTp.toNonNullable();
    return _interfaceRels.containsKey(iTp) && _interfaceRels[iTp]!.contains(tp);
  }

  Set<DartType> get mapTypes {
    return _mapTypes;
  }

  bool isSpecializable(DartType tp) {
    return _interfaceRels.containsKey(tp.toNonNullable());
  }

  Set<DartType> interfaces(DartType tp) {
    tp = tp.toNonNullable();
    if (_interfaceRels.containsKey(tp)) {
      return _interfaceRels[tp]!;
    }
    throw "NotFound";
  }

  DartType indexType(DartType tp) {
    tp = tp.toNonNullable();
    if (_indexedBy.containsKey(tp)) {
      return _indexedBy[tp]!;
    }
    throw "NotFound";
  }

  Set<DartType> indexableElementTypes(DartType tp) {
    if (_indexableElementOf.containsKey(tp)) {
      return _indexableElementOf[tp]!;
    }
    throw "NotFound";
  }

  bool isIndexableElementType(DartType tp) {
    return _indexableElementOf.containsKey(tp);
  }

  DartType elementType(DartType tp) {
    tp = tp.toNonNullable();
    if (_subscriptsTo.containsKey(tp)) {
      return _subscriptsTo[tp]!;
    }
    throw "NotFound";
  }

  Set<DartType> get iterableTypes1 {
    return _iterableTypes1;
  }

  Set<String> uniOps(DartType tp) {
    if (_uniOps.containsKey(tp)) {
      return _uniOps[tp]!;
    }
    return <String>{};
  }

  Set<String> binOps(DartType tp) {
    if (_binOps.containsKey(tp)) {
      return _binOps[tp]!.keys.toSet();
    }
    return <String>{};
  }

  Set<List<DartType>> binOpParameters(DartType tp, String op) {
    if (_binOps.containsKey(tp) &&
        _binOps[tp]!.containsKey(op)) {
      return _binOps[tp]![op]!;
    }
    throw "NotFound";
  }

  Set<String> assignOps(DartType tp) {
    if (_assignOps.containsKey(tp)) {
      return _assignOps[tp]!.keys.toSet();
    }
    return <String>{};
  }

  Set<DartType> assignOpRhs(DartType tp, String op) {
    if (_assignOps.containsKey(tp) &&
        _assignOps[tp]!.containsKey(op)) {
      return _assignOps[tp]![op]!;
    }
    return <DartType>{};
  }

  bool hasConstructor(DartType tp) {
    tp = tp.toNonNullable();
    return _constructors.containsKey(tp);
  }

  Set<String> constructors(DartType tp) {
    tp = tp.toNonNullable();
    if (_constructors.containsKey(tp)) {
      return _constructors[tp]!.keys.toSet();
    }
    return <String>{};
  }

  List<DartType> constructorParameters(DartType tp, String constructor) {
    tp = tp.toNonNullable();
    if (_constructors.containsKey(tp) &&
        _constructors[tp]!.containsKey(constructor)) {
      return _constructors[tp]![constructor]!;
    }
    throw "NotFound";
  }

  Set<DartType> get allTypes {
    return _allTypes;
  }

''');

  print("  static const VOID = DartType._withName('void', false);");
  print("  static const VOID_NULLABLE = VOID;");
  var instTypes = <String>{};

  // Generate one static DartType instance for all instantiable types.
  // TODO (felih): maybe add void type?
  allTypes.forEach((baseType) {
    var constName = getConstName(baseType.displayName);
    instTypes.add(constName);
    if (!subclass) {
      print('  static const $constName = '
          "DartType._withName('${baseType.displayName}', false);");
      print('  static const ${constName}_NULLABLE = '
          "DartType._withName('${baseType.displayName}', true);");
    }
  });

  if (!subclass) {
    // Generate one static DartType instance for all non instantiable types.
    // These are required to resolve interface relations, but should not be
    // used directly to generate dart programs.
    print('');
    print('  // NON INSTANTIABLE' '');
    interfaceRels.keys.forEach((constName) {
      if (instTypes.contains(constName)) return;
      print('  static const $constName = '
          "DartType._withName('__$constName', false);");
      print('  static const ${constName}_NULLABLE = '
          "DartType._withName('__$constName', true);");
    });
  }

  // Generate a list of all instantiable types.
  print('');
  print('''
  // All types extracted from analyzer.
  static const _allTypes = {''');
  filterTypesSet(instTypes, fp: fp, flatTp: flatTp).forEach((constName) {
    print("    ${subclass ? "DartType." : ""}$constName,");
    print("    ${subclass ? "DartType." : ""}${constName}_NULLABLE,");
  });
  print('  };');

  print('');
  print('''
  // All List<E> types: LIST_INT, LIST_STRING, etc.''');
  printTypeSet('_listTypes', listTypes, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // All Set types: SET_INT, SET_STRING, etc.''');
  printTypeSet('_setTypes', setTypes, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // All Map<K, V> types: MAP_INT_STRING, MAP_DOUBLE_BOOL, etc.''');
  printTypeSet('_mapTypes', mapTypes, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // All collection types: list, map and set types.''');
  printTypeSet('_collectionTypes', {...listTypes, ...setTypes, ...mapTypes},
      fp: fp, flatTp: flatTp);

  print('');
  print('''
  // All growable types: list, map, set and string types.''');
  printTypeSet(
      '_growableTypes', {...listTypes, ...setTypes, ...mapTypes, 'STRING'},
      fp: fp, flatTp: flatTp);

  if (!subclass) {
    print('');
    print(
        '  // All floating point types: DOUBLE, SET_DOUBLE, MAP_X_DOUBLE, etc.');
    printTypeSet('_fpTypes', fpTypes);
  }

  print('');
  print('''
  // All trivially indexable types: Map types and List types.
  // Elements of these can be written and read by [], unlike Set
  // which uses getElementAt to access individual elements.''');
  printTypeSet('_indexableTypes', indexableTypes, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // Map type to the resulting type when subscripted.
  // Example: List<String> subscripts to String.''');
  printTypeMap1('_subscriptsTo', subscriptsTo, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // Map type to type required as index.
  // Example: List<String> is indexed by int,
  // Map<String, double> indexed by String.''');
  printTypeMap1('_indexedBy', indexedBy, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // Map type to a Set of types that contain it as an element.
  // Example: String is element of List<String> and Map<int, String>''');
  printTypeMap2('_elementOf', elementOf, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // Map type to a Set of types that contain it as an indexable element.
  // Same as element of, but without Set types.''');
  printTypeMap2('_indexableElementOf', indexableElementOf,
      fp: fp, flatTp: flatTp);

  print('');
  print('''
  // All iterable types: Set types + List types.
  // These can be used in for(x in <iterable type>),
  // therefore Map is not included.''');
  printTypeSet('_iterableTypes1', iterableTypes1, fp: fp, flatTp: flatTp);

  if (!subclass) {
    print('');
    print('''
  // Complex types: Collection types instantiated with nested argument
  // e.g Map<List<>, >.''');
    printTypeSet('_complexTypes', complexTypes);
  }

  print('');
  print('''
  // Map Interface type to Set of types that implement it.
  // Example: interface num is implemented by int and double.''');
  printTypeMap2('_interfaceRels', interfaceRels, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // Map type to a list of constructors names with a list of constructor
  // parameter types.''');
  printTypeMap3('_constructors', constructors, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // Map type to a list of binary operators with set of the respective
  // types for the first and second operand.''');
  printTypeMap4('_binOps', binOps, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // Map type to a list of available unary operators.''');
  printTypeMapSet('_uniOps', uniOps, fp: fp, flatTp: flatTp);

  print('');
  print('''
  // Map type to a list of assignment operators with a set of the
  // assignable right hand side types.''');
  printTypeMap3Set('_assignOps', assignOps, fp: fp, flatTp: flatTp);

  print('}');
  print('');
}

// Returns true if type can be set and get via [].
bool isIndexable(InterfaceType tp) {
  var isIndexable = false;
  for (var method in tp.methods) {
    if (method.name == '[]') {
      isIndexable = true;
      break;
    }
  }
  return isIndexable;
}

// Returns true if iTypeName == typeName or if
// iTypeName is an interface type that is implemented by typeName.
// List<int> is interface of Int8List
bool isInterfaceOf(String iTypName, String typName) {
  return iTypName == typName ||
      (interfaceRels.containsKey(iTypName) &&
          interfaceRels[iTypName]!.contains(typName));
}

// Filter operator parameters so that the more specific types are discarded if
// the respective interface type is already in the list.
// This is required not only to give each parameter type equal probability but
// also so that dartfuzz can efficiently filter floating point types from the
// interface relations.
Set<List<String>> filterOperator(Set<List<String>> op) {
  var newOp = <List<String>>{};
  if (op.length < 2) return op;
  for (var params1 in op) {
    var keep = false;
    for (var params2 in op) {
      for (var k = 0; k < params1.length; ++k) {
        if (!isInterfaceOf(params2[k], params1[k])) {
          keep = true;
          break;
        }
      }
      if (keep) break;
    }
    if (keep) {
      newOp.add(params1);
    }
  }
  return newOp;
}

// See comment on filterOpterator.
void filterOperators(Set<InterfaceType> allTypes) {
  for (var tp in allTypes) {
    var typName = getConstName(tp.displayName);
    if (!binOps.containsKey(typName)) continue;
    for (var op in binOps[typName]!.keys) {
      binOps[typName]![op] = filterOperator(binOps[typName]![op]!);
    }
  }
}

// Filters methods based on a manually maintained exclude list.
//
// Excluded methods should be associated with an issue number so they can be
// re-enabled after the issue is resolved.
bool isExcludedMethod(InterfaceType tp, MethodElement method) {
  // TODO(bkonyi): Enable operator / for these types after we resolve
  // https://github.com/dart-lang/sdk/issues/39890
  if (((tp.displayName == 'Float32x4') && (method.name == '/')) ||
      ((tp.displayName == 'Float64x2') && (method.name == '/'))) {
    return true;
  }
  return false;
}

// Extract all binary and unary operators for tp.
// Operators are stored by return type in the following way:
// return type: { operator: { parameter types } }
// Example: bool: { == : { [int, int], [double, double] }}
//          int: {'~', '-'},
// Does not recurse into interfaces and superclasses of tp.
void getOperatorsForTyp(String typName, InterfaceType tp, fromLiteral) {
  for (var method in tp.methods) {
    // If the method is manually excluded, skip it.
    if (isExcludedMethod(tp, method)) continue;

    // Detect whether tp can be parsed from a literal (dartfuzz.dart can
    // already handle that).
    // This is usually indicated by the presence of the static constructor
    // 'castFrom' or 'parse'.
    if (method.isStatic &&
        (method.name == 'castFrom' || method.name == 'parse')) {
      fromLiteral.add(getConstName(tp.displayName));
    }
    // Hack: dartfuzz.dart already handles subscripts, therefore we exclude
    // them from the generated type table.
    if (method.name.startsWith('[]')) continue;
    if (method.isOperator) {
      // TODO (felih): Include support for type 'dynamic'.
      var skip = false;
      for (var p in method.parameters) {
        if (getConstName(p.type.displayName) == 'DYNAMIC') {
          skip = true;
          break;
        }
      }
      if (skip) continue;
      if (method.parameters.length == 1) {
        // Get binary operators.

        var retTypName = getConstName(method.returnType.displayName);
        if (method.returnType.nullabilitySuffix != NullabilitySuffix.none) {
          retTypName += '_NULLABLE';
        }
        binOps[retTypName] ??= <String, Set<List<String>>>{};
        binOps[retTypName]![method.name] ??= <List<String>>{};

        var rhsTypName = getConstName(method.parameters[0].type.displayName);
        if (method.parameters[0].type.nullabilitySuffix !=
            NullabilitySuffix.none) {
          rhsTypName += '_NULLABLE';
        }

        // TODO (felih): no hashing for List<String> ?
        // if i remove this test i will get duplicates even though it is a Set.
        var present = false;
        for (var o in binOps[retTypName]![method.name]!) {
          if (o[0] == typName && o[1] == rhsTypName) {
            present = true;
            break;
          }
        }
        if (!present) {
          binOps[retTypName]![method.name]!.add([typName, rhsTypName]);
        }

        // Add some assignment operators corresponding to the binary operators.
        // Example: for '+' add '+='.
        // Bool types have to be filtered because boolean binary operators
        // can not be used to derive assignment operators in this way, e.g.
        // <= is not a valid assignment operator for bool types.
        if (retTypName != 'BOOL') {
          assignOps[retTypName] ??= <String, Set<String>>{};
          var ao = method.name + '=';
          assignOps[retTypName]![ao] ??= <String>{};
          assignOps[retTypName]![ao]!.add(rhsTypName);
        }
      } else {
        // Get unary operators.
        uniOps[typName] ??= <String>{};
        var uo = method.name;
        // Hack: remove unary from operator so that the operator name can be
        // used directly for source code generation.
        if (uo.startsWith('unary')) uo = '-';
        uniOps[typName]!.add('\'$uo\'');
      }
    }
  }
}

bool typesEqualModuloNullability(DartType a, DartType b) {
  // The analyzer's DartType doesn't provide conversions to change nullability.
  // Comparing by name isn't correct in general, but it works for the core
  // libraries because there are no simple name conflicts.
  return a.displayName == b.displayName;
}

// Extract all binary and unary operators for all types.
void getOperators(Set<InterfaceType> allTypes) {
  // Set of types that can be constructed directly from literals and do
  // not need special constructors (e.g. List<int> = [1, 2] as opposed to
  // Int8List int8list = Int8List.fromList([1, 2]) ).
  var fromLiteral = <String>{};

  // getOperatorsForTyp uses a heuristic to detect which types can be
  // constructed from a literal, but the heuristic misses the String type
  // so we have to add it manually.
  fromLiteral.add('STRING');
  // Get binary, unary and assignment operators.
  for (var tp in allTypes) {
    var typName = getConstName(tp.displayName);
    // Manually add basic assignment operators which each type supports.
    assignOps[typName] ??= <String, Set<String>>{};
    assignOps[typName]!['='] = {typName};
    getOperatorsForTyp(typName, tp, fromLiteral);

    var typNameNullable = typName + "_NULLABLE";
    assignOps[typNameNullable] ??= <String, Set<String>>{};
    assignOps[typNameNullable]!['='] = {typName, typNameNullable};
    assignOps[typNameNullable]!['??='] = {typName, typNameNullable};
  }

  // Add some static ops not extractable from dart:core/typed_data.
  for (var typName in binOps.keys.toList()) {
    if (typName.endsWith("_NULLABLE")) continue;

    var typNameNullable = typName + "_NULLABLE";
    binOps[typNameNullable] ??= <String, Set<List<String>>>{};
    binOps[typNameNullable]!['??'] = {
      [typNameNullable, typName],
      [typNameNullable, typNameNullable],
    };

    binOps[typName] ??= <String, Set<List<String>>>{};
    binOps[typName]!['??'] = {
      [typNameNullable, typName],
    };
  }
  binOps['BOOL'] ??= <String, Set<List<String>>>{};
  binOps['BOOL']!['&&'] = {
    ['BOOL', 'BOOL'],
  };
  binOps['BOOL']!['||'] = {
    ['BOOL', 'BOOL'],
  };
  uniOps['BOOL'] ??= <String>{};
  uniOps['BOOL']!.add('\'!\'');

  // Get constructors.
  for (var tp in allTypes) {
    var typName = getConstName(tp.displayName);
    // Skip types that are constructable from a literal.
    if (fromLiteral.contains(typName)) {
      continue;
    }
    for (var constructor in tp.constructors) {
      if (shouldFilterConstructor(tp, constructor)) continue;
      var params = <String>[];
      var canConstruct = true;
      for (var p in constructor.parameters) {
        var tstr = getConstName(p.type.displayName);
        if (tstr == 'DYNAMIC' || tstr == 'OBJECT') {
          tstr = 'INT';
        } else if (!allTypes
            .any((a) => typesEqualModuloNullability(a, p.type))) {
          // Exclude constructors that have an unsupported parameter type.
          canConstruct = false;
          break;
        }
        // Only add positional required parameters.
        // TODO (felih): include named and optional parameters.
        if (!p.isNamed) params.add(tstr);
      }
      if (!canConstruct) continue;

      constructors[typName] ??= <String, List<String>>{};
      constructors[typName]![constructor.name] = params;
    }
  }
  // Removed redundant specialized parameter types.
  // E.g. if num is already contained remove bool and int.
  filterOperators(allTypes);
}

bool shouldFilterConstructor(InterfaceType tp, ConstructorElement cons) {
  // Filter private constructors.
  if (cons.name.startsWith('_')) {
    return true;
  }
  // Constructor exclude list
  // TODO(bkonyi): Enable Float32x4.fromInt32x4Bits after we resolve
  // https://github.com/dart-lang/sdk/issues/39890
  if ((tp.displayName == 'Float32x4') && (cons.name == 'fromInt32x4Bits')) {
    return true;
  }
  return false;
}

// Analyze types to extract element and subscript relations
// as well as precision type attributes.
void analyzeTypes(Set<InterfaceType> allTypes) {
  // Extract basic floating point types.
  for (var tp in allTypes) {
    if (tp.displayName.contains('Float') ||
        tp.displayName.contains('float') ||
        tp.displayName.contains('double') ||
        tp.displayName.contains('Double')) {
      fpTypes.add(getConstName(tp.displayName));
    }
  }

  // Analyze all types to extract information useful for dart code generation.
  for (var tp in allTypes) {
    final typName = getConstName(tp.displayName);

    // Find topmost interface type, e.g. List<int> is interface for Int8List.
    var iTyp = tp;
    while (iTyp.typeArguments.isEmpty && iTyp.interfaces.isNotEmpty) {
      iTyp = tp.interfaces[0];
    }

    // Group current type with their respective type group.
    if (iTyp.name == 'Set') setTypes.add(typName);
    if (iTyp.name == 'List') listTypes.add(typName);
    if (iTyp.name == 'Map') mapTypes.add(typName);

    if (iTyp.typeArguments.length == 1) {
      // Analyze Array, List and Set types.
      var argName = getConstName(iTyp.typeArguments[0].displayName);
      subscriptsTo[typName] = argName;
      elementOf[argName] ??= <String>{};
      elementOf[argName]!.add(typName);
      if (isIndexable(iTyp)) {
        indexableElementOf[argName] ??= <String>{};
        indexableElementOf[argName]!.add(typName);
        indexedBy[typName] = 'INT';
        indexableTypes.add(typName);
      }
      // Check if type is floating point precision.
      if (fpTypes.contains(typName) || fpTypes.contains(argName)) {
        fpTypes.add(typName);
      }
    } else if (iTyp.typeArguments.length == 2) {
      if (isIndexable(iTyp)) {
        // Analyze Map and MapEntry types.
        var argName0 = getConstName(iTyp.typeArguments[0].displayName);
        var argName1 = getConstName(iTyp.typeArguments[1].displayName);
        subscriptsTo[typName] = argName1;
        elementOf[argName1] ??= <String>{};
        elementOf[argName1]!.add(typName);
        indexableElementOf[argName1] ??= <String>{};
        indexableElementOf[argName1]!.add(typName);
        indexedBy[typName] = argName0;
        indexableTypes.add(typName);
        // Check if type is floating point precision.
        if (fpTypes.contains(typName) ||
            fpTypes.contains(argName0) ||
            fpTypes.contains(argName1)) {
          fpTypes.add(typName);
        }
      }
    }
  }
}

// Split types into sets of types with none, one and two parameters
// respectively.
void getParameterizedTypes(
    Set<InterfaceType> allTypes, // Set of all types.
    Set<InterfaceType> pTypes1, // Out: types with one parameter e.g. List.
    Set<InterfaceType> pTypes2, // Out: types with two parameters e.g. Map.
    Set<InterfaceType> iTypes) {
  // Out: types with no parameters.
  for (var tp in allTypes) {
    if (tp.typeArguments.length == 1 &&
        (tp.typeArguments[0].name == 'E' || tp.typeArguments[0].name == 'T')) {
      pTypes1.add(tp);
    } else if (tp.typeArguments.length == 2 &&
        tp.typeArguments[0].name == 'K' &&
        tp.typeArguments[1].name == 'V') {
      pTypes2.add(tp);
    } else {
      iTypes.add(tp);
    }
  }
}

// Generate new types by instantiating types with one and two parameters
// with the types having no parameters (or the parameters of which have
// already been instantiated).
// There will be no more then maxNew types generated.
Set<InterfaceType> instantiatePTypes(
    Set<InterfaceType> pTypes1, // Types with one parameter.
    Set<InterfaceType> pTypes2, // Types with two parameters.
    Set<InterfaceType> iTypes, // Types with no parameters.
    {double maxNew = 10000.0}) {
  // Maximum number of newly generated types.
  var newITypes = <InterfaceType>{};

  // Calculate the total number of new types if all combinations were used.
  int nNew = pTypes1.length * iTypes.length +
      pTypes2.length * iTypes.length * iTypes.length;
  // Calculate how many generated types have to be skipped in order to stay
  // under the maximum number set for generating new types (maxNew).
  double step = maxNew / nNew.toDouble();
  double cntr = 0.0;

  // Instantiate List and Set types.
  pTypes1.forEach((pType) {
    iTypes.forEach((iType) {
      cntr += step;
      if (cntr >= 1.0) {
        cntr -= 1.0;
      } else {
        return;
      }
      InterfaceType ptx = pType.element.instantiate(
        typeArguments: [iType],
        nullabilitySuffix: NullabilitySuffix.star,
      );
      newITypes.add(ptx);
      if (iType.typeArguments.isNotEmpty) {
        complexTypes.add(getConstName(ptx.displayName));
      }
    });
  });

  // Instantiate Map types.
  pTypes2.forEach((pType) {
    iTypes.forEach((iType1) {
      iTypes.forEach((iType2) {
        cntr += step;
        if (cntr >= 1.0) {
          cntr -= 1.0;
        } else {
          return;
        }
        InterfaceType ptx = pType.element.instantiate(
          typeArguments: [iType1, iType2],
          nullabilitySuffix: NullabilitySuffix.star,
        );
        newITypes.add(ptx);
        if (iType1.typeArguments.isNotEmpty ||
            iType2.typeArguments.isNotEmpty) {
          complexTypes.add(getConstName(ptx.displayName));
        }
      });
    });
  });

  // Add instantiated types to the set of types with no free parameters.
  return iTypes.union(newITypes);
}

Set<InterfaceType> instantiateAllTypes(
    Set<InterfaceType> allTypes, Set<String> iTypeFilter, int depth,
    {double maxNew = 10000.0}) {
  // Types with one parameter (List, Set).
  var pTypes1 = <InterfaceType>{};
  // Types with two parameters (Map).
  var pTypes2 = <InterfaceType>{};
  // Types with no parameters or parameters of which have already been
  // instantiated.
  var iTypes = <InterfaceType>{};
  // Fill type sets with respective parameter types.
  getParameterizedTypes(allTypes, pTypes1, pTypes2, iTypes);

  // Filter the list of zero parameter types to exclude
  // complex types like Int8List.
  var filteredITypes = <InterfaceType>{};
  for (var iType in iTypes) {
    if (iTypeFilter.contains(iType.displayName)) {
      filteredITypes.add(iType);
    }
  }

  // Instantiate types with one or two free parameters.
  // Concatenate the newly instantiated types with the previous set of
  // instantiated or zero parameter types to be used as input for the next
  // round or instantiation.
  // Each iteration constructs more nested types like
  // Map<Map<int, int>, List<int>>.
  for (var i = 0; i < depth + 1; ++i) {
    double mn = max(1.0, maxNew / (depth + 1.0));
    filteredITypes = filteredITypes
        .union(instantiatePTypes(pTypes1, pTypes2, filteredITypes, maxNew: mn));
  }

  return iTypes.union(filteredITypes);
}

// Heuristic of which types to include:
// count the number of operators and
// check if the type can be constructed from a literal.
int countOperators(ClassElement ce) {
  var no = 0;
  ce.methods.forEach((method) {
    if (method.isOperator) {
      no++;
    }
    // Detect whether type can be parsed from a literal (dartfuzz.dart can
    // already handle that).
    // This is usually indicated by the presence of the static constructor
    // 'castFrom' or 'parse'.
    if (method.isStatic &&
        (method.name == 'castFrom' || method.name == 'parse')) {
      no += 100;
    }
    for (var ci in ce.interfaces) {
      no += countOperators(ci.element);
    }
  });
  return no;
}

// Analyze typed_data and core libraries to extract data types.
Future<void> getDataTypes(Set<InterfaceType> allTypes, String? dartTop) async {
  final session = GenUtil.createAnalysisSession(dartTop);

  // Visit libraries for type table generation.
  await visitLibraryAtUri(session, 'dart:typed_data', allTypes);
  await visitLibraryAtUri(session, 'dart:core', allTypes);
}

Future<void> visitLibraryAtUri(
    AnalysisSession session, String uri, Set<InterfaceType> allTypes) async {
  var libPath = session.uriConverter.uriToPath(Uri.parse(uri));
  var result = await session.getResolvedLibrary2(libPath!);
  if (result is ResolvedLibraryResult) {
    visitLibrary(result.element, allTypes);
  } else {
    throw StateError('Unable to resolve "$uri"');
  }
}

void visitLibrary(LibraryElement library, Set<InterfaceType> allTypes) {
  // This uses the element model to traverse the code. The element model
  // represents the semantic structure of the code. A library consists of
  // one or more compilation units.
  for (var unit in library.units) {
    visitCompilationUnit(unit, allTypes);
  }
}

void visitCompilationUnit(
    CompilationUnitElement unit, Set<InterfaceType> allTypes) {
  // Each compilation unit contains elements for all of the top-level
  // declarations in a single file, such as variables, functions, and
  // classes. Note that `types` only returns classes. You can use
  // `mixins` to visit mixins, `enums` to visit enum, `functionTypeAliases`
  // to visit typedefs, etc.
  for (var classElement in unit.types) {
    if (classElement.isPublic) {
      // Hack: Filter out some difficult types, abstract types and types that
      // have methods with abstract type parameters.
      // TODO (felih): include filtered types.
      if (classElement.name.startsWith('Unmodifiable') ||
          classElement.name.startsWith('Iterable') ||
          classElement.name.startsWith('BigInt') ||
          classElement.name.startsWith('DateTime') ||
          classElement.name.startsWith('Uri') ||
          (classElement.name == 'Function') ||
          (classElement.name == 'Object') ||
          (classElement.name == 'Match') ||
          (classElement.name == 'RegExpMatch') ||
          (classElement.name == 'pragma') ||
          (classElement.name == 'LateInitializationError') ||
          (classElement.name == 'ByteBuffer') ||
          (classElement.name == 'TypedData') ||
          (classElement.name == 'Sink') ||
          (classElement.name == 'Pattern') ||
          (classElement.name == 'StackTrace') ||
          (classElement.name == 'StringSink') ||
          (classElement.name == 'Type') ||
          (classElement.name == 'Pattern') ||
          (classElement.name == 'Invocation') ||
          (classElement.name == 'StackTrace') ||
          (classElement.name == 'NoSuchMethodError') ||
          (classElement.name == 'Comparable') ||
          (classElement.name == 'BidirectionalIterator') ||
          (classElement.name == 'Iterator') ||
          (classElement.name == 'Stopwatch') ||
          (classElement.name == 'OutOfMemoryError')) {
        continue;
      }
      allTypes.add(classElement.thisType);
    }
  }
}

// Get all interface implemented by type.
Set<String> getInterfaces(InterfaceType tp) {
  var iTypes = <String>{};
  for (var iTyp in tp.interfaces) {
    var ifTypName = getConstName(iTyp.displayName);
    iTypes.add(ifTypName);
    iTypes = iTypes.union(getInterfaces(iTyp));
  }
  return iTypes;
}

// Get interface and inheritance relationships for all types.
void getInterfaceRels(Set<InterfaceType> allTypes) {
  for (var tp in allTypes) {
    var typName = getConstName(tp.displayName);
    for (var ifTypName in getInterfaces(tp)) {
      interfaceRels[ifTypName] ??= <String>{};
      interfaceRels[ifTypName]!.add(typName);
      if (ifTypName.contains('ITERABLE')) {
        iterableTypes1.add(typName);
      }
    }
    for (var it in tp.element.allSupertypes) {
      var ifTypName = getConstName(it.displayName);
      interfaceRels[ifTypName] ??= <String>{};
      interfaceRels[ifTypName]!.add(typName);
    }
  }
  // If interface can be instantiated,
  // add it to the relation list so that we can
  // do tp1 = oneof(interfaceRels[tp2]) in dartfuzz with a chance of
  // tp1 == tp1.
  for (var tp in allTypes) {
    var typName = getConstName(tp.displayName);
    if (interfaceRels.containsKey(typName)) {
      interfaceRels[typName]!.add(typName);
    }
  }
}

void main(List<String> arguments) async {
  final parser = ArgParser()
    ..addOption('dart-top', help: 'explicit value for \$DART_TOP')
    ..addOption('depth',
        help: 'Nesting depth, e.g. List<String> is depth 0, '
            'List<List<String>>'
            'is depth 1. Remark: dart type tables grow '
            'exponentially with this, '
            'therefore types with higher nesting '
            'depth are partially filtered.',
        defaultsTo: '1');
  var results;
  try {
    results = parser.parse(arguments);
  } catch (e) {
    print('Usage: dart gen_type_table.dart [OPTIONS]\n${parser.usage}\n$e');
    exitCode = 255;
    return;
  }
  var depth = int.parse(results['depth']);
  var allTypes = <InterfaceType>{};
  // Filter types to instantiate parameterized types with, this excludes
  // complex types like Int8List (might be added later).
  var iTypeFilter = <String>{'int', 'bool', 'double', 'String'};
  // Extract basic types from dart::core and dart::typed_data.
  await getDataTypes(allTypes, results['dart-top']);
  // Instantiate parameterized types like List<E>.
  allTypes = instantiateAllTypes(allTypes, iTypeFilter, depth, maxNew: 10000.0);
  // Extract interface Relations between types.
  getInterfaceRels(allTypes);
  // Extract operators from instantiated types.
  getOperators(allTypes);
  // Analyze instantiated types to get elementof/subscript and floating point
  // information.
  analyzeTypes(allTypes);
  // Print everything.
  printTypeTable(allTypes);
  printTypeTable(allTypes, fp: false);
  printTypeTable(allTypes, flatTp: true);
  printTypeTable(allTypes, fp: false, flatTp: true);
}
