// 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/dart format \
//   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.getResolvedLibrary(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);
}
