// 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:args/args.dart';

import 'package:analyzer/dart/element/type.dart';
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 '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 =
    new Map<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 =
    new Map<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 =
    new Map<String, Map<String, Set<List<String>>>>();

// Map type to a list of available unary operators.
Map<String, Set<String>> uniOps = new Map<String, Set<String>>();

//
// Type grouping.
//

// All Set<E> types: SET_INT, SET_STRING, etc.
Set<String> setTypes = new Set<String>();

// All Map<K, V> types: MAP_INT_STRING, MAP_DOUBLE_BOOL, etc.
Set<String> mapTypes = new Set<String>();

// All List<E> types: LIST_INT, LIST_STRING, etc.
Set<String> listTypes = new Set<String>();

// All floating point types: DOUBLE, SET_DOUBLE, MAP_X_DOUBLE, etc.
Set<String> fpTypes = new Set<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 = new Set<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 = new Set<String>();

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

//
// Type relations.
//

// Map type to the resulting type when subscripted.
// Example: List<String> subscripts to String.
Map<String, String> subscriptsTo = new Map<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 = new Map<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 = new Map<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 = new Map<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 = new Map<String, Set<String>>();

// Convert analyzer's displayName to constant name used by dartfuzz.
// Example: Set<int, String> -> SET_INT_STRING
String getConstName(String displayName) {
  String 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 (String 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}) {
  Set<List<String>> filteredParams = <List<String>>{};
  for (List<String> 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}) {
  Set<String> filteredParams = <String>{};
  for (String 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}) {
  Map<String, Set<List<String>>> filteredOps = <String, Set<List<String>>>{};
  operators.forEach((op, parameterList) {
    Set<List<String>> 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}) {
  Map<String, List<String>> 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}) {
  Map<String, Set<String>> filteredOps = <String, Set<String>>{};
  operators.forEach((op, parameterSet) {
    Set<String> 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}) {
  Map<String, Map<String, Set<List<String>>>> filteredTypes =
      <String, Map<String, Set<List<String>>>>{};
  types.forEach((baseType, ops) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return true;
    }
    Map<String, Set<List<String>>> 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 bool subclass = !fp || flatTp;
  final String prefix = "${subclass ? "DartType." : ""}";
  print("  static const Map<DartType, Map<String, " +
      "Set<List<DartType>>>> ${name} = {");
  Map<String, Map<String, Set<List<String>>>> 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 (String 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}) {
  Map<String, Map<String, Set<String>>> filteredTypes =
      <String, Map<String, Set<String>>>{};
  types.forEach((baseType, ops) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return true;
    }
    Map<String, Set<String>> 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 bool subclass = !fp || flatTp;
  final String prefix = "${subclass ? "DartType." : ""}";
  print("  static const Map<DartType, " +
      "Map<String, Set<DartType>>> ${name} = {");

  Map<String, Map<String, Set<String>>> 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 (String 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}) {
  Map<String, Map<String, List<String>>> filteredTypes =
      <String, Map<String, List<String>>>{};
  types.forEach((baseType, ops) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return true;
    }
    Map<String, List<String>> 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 bool subclass = !fp || flatTp;
  final String 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 (String 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}) {
  Map<String, Set<String>> filteredTypes = <String, Set<String>>{};
  types.forEach((baseType, parameterSet) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return true;
    }
    Set<String> 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 bool subclass = !fp || flatTp;
  final String 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 (String 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}) {
  Map<String, String> filteredTypes = <String, String>{};
  types.forEach((baseType, paramType) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return true;
    }
    if (shouldFilterType(paramType, fp: fp, flatTp: flatTp)) {
      return true;
    }
    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 bool subclass = !fp || flatTp;
  final String 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}) {
  Set<String> filteredTypes = {};
  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 bool subclass = !fp || flatTp;
  final String prefix = "${subclass ? "DartType." : ""}";
  stdout.write("  static const Set<DartType> ${name} = {");
  for (String typName in filterTypesSet(types, fp: fp, flatTp: flatTp).toList()
    ..sort()) {
    stdout.write("${prefix}$typName, ");
  }
  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}) {
  Map<String, Set<String>> filteredTypes = <String, Set<String>>{};
  types.forEach((baseType, params) {
    if (shouldFilterType(baseType, fp: fp, flatTp: flatTp)) {
      return true;
    }
    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 bool subclass = !fp || flatTp;
  final String 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 bool 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.

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

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

  print('class $className'
      '${subclass ? " extends DartType" : ""} {');
  print("  final String name;");
  if (!subclass) {
    print("  const DartType._withName(this.name);");
    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) : super._withName(name);');
  }

  print("""
  const $className() : name = null;
  static bool isListType(DartType tp) {
    return DartType._listTypes.contains(tp);
  }

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

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

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

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

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

  Set<DartType> get mapTypes {
    return _mapTypes;
  }

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

  Set<DartType> interfaces(DartType tp) {
    if (_interfaceRels.containsKey(tp)) {
      return _interfaceRels[tp];
    }
    return null;
  }

  DartType indexType(DartType tp) {
    if (_indexedBy.containsKey(tp)) {
      return _indexedBy[tp];
    }
    return null;
  }

  Set<DartType> indexableElementTypes(DartType tp) {
    if (_indexableElementOf.containsKey(tp)) {
      return _indexableElementOf[tp];
    }
    return null;
  }

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

  DartType elementType(DartType tp) {
    if (_subscriptsTo.containsKey(tp)) {
      return _subscriptsTo[tp];
    }
    return null;
  }

  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];
    }
    return null;
  }

  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) {
    return _constructors.containsKey(tp);
  }

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

  List<DartType> constructorParameters(DartType tp, String constructor) {
    if (_constructors.containsKey(tp) &&
        _constructors[tp].containsKey(constructor)) {
      return _constructors[tp][constructor];
    }
    return null;
  }

  Set<DartType> get allTypes {
    return _allTypes;
  }

""");

  print("  static const VOID = const " + "DartType._withName(\"void\");");
  Set<String> instTypes = {};

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

  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 true;
      print("  static const ${constName} = const " +
          "DartType._withName(\"__${constName}\");");
    });
  }

  // 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("  };");

  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) {
  bool 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) {
  Set<List<String>> newOp = new Set<List<String>>();
  if (op.length < 2) return op;
  for (List<String> params1 in op) {
    bool keep = false;
    for (List<String> params2 in op) {
      for (int 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 (InterfaceType tp in allTypes) {
    String typName = getConstName(tp.displayName);
    if (!binOps.containsKey(typName)) continue;
    for (String 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 (MethodElement 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'.
      bool 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.

        String retTypName = getConstName(method.returnType.displayName);
        binOps[retTypName] ??= new Map<String, Set<List<String>>>();
        binOps[retTypName][method.name] ??= new Set<List<String>>();

        String rhsTypName = getConstName(method.parameters[0].type.displayName);

        // TODO (felih): no hashing for List<String> ?
        // if i remove this test i will get duplicates even though it is a Set.
        bool present = false;
        for (List<String> 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] ??= new Map<String, Set<String>>();
          String ao = method.name + '=';
          assignOps[retTypName][ao] ??= new Set<String>();
          assignOps[retTypName][ao].add(rhsTypName);
        }
      } else {
        // Get unary operators.
        uniOps[typName] ??= new Set<String>();
        String 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\'');
      }
    }
  }
}

// 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]) ).
  Set<String> fromLiteral = new Set<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 (InterfaceType tp in allTypes) {
    String typName = getConstName(tp.displayName);
    // Manually add basic assignment operators which each type supports.
    assignOps[typName] ??= new Map<String, Set<String>>();
    assignOps[typName]['='] = {typName};
    assignOps[typName]['??='] = {typName};
    getOperatorsForTyp(typName, tp, fromLiteral);
  }

  // Add some static ops not extractable from dart:core/typed_data.
  for (String typName in binOps.keys) {
    binOps[typName] ??= new Map<String, Set<List<String>>>();
    binOps[typName]['??'] = {
      [typName, typName],
    };
  }
  binOps['BOOL'] ??= new Map<String, Set<List<String>>>();
  binOps['BOOL']['&&'] = {
    ['BOOL', 'BOOL'],
  };
  binOps['BOOL']['||'] = {
    ['BOOL', 'BOOL'],
  };
  uniOps['BOOL'] ??= new Set<String>();
  uniOps['BOOL'].add('\'!\'');

  // Get constructors.
  for (InterfaceType tp in allTypes) {
    String typName = getConstName(tp.displayName);
    // Skip types that are constructable from a literal.
    if (fromLiteral.contains(typName)) {
      continue;
    }
    for (ConstructorElement constructor in tp.constructors) {
      if (shouldFilterConstructor(tp, constructor)) continue;
      List<String> params = new List<String>();
      bool canConstruct = true;
      for (var p in constructor.parameters) {
        String tstr = getConstName(p.type.displayName);
        if (tstr == "DYNAMIC" || tstr == "OBJECT") {
          tstr = "INT";
        } else if (!allTypes.contains(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] ??= new Map<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 (InterfaceType 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 (InterfaceType tp in allTypes) {
    final typName = getConstName(tp.displayName);

    // Find topmost interface type, e.g. List<int> is interface for Int8List.
    InterfaceType iTyp = tp;
    while (iTyp.typeArguments.isEmpty && !iTyp.interfaces.isEmpty) {
      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.
      String argName = getConstName(iTyp.typeArguments[0].displayName);
      subscriptsTo[typName] = argName;
      elementOf[argName] ??= new Set<String>();
      elementOf[argName].add(typName);
      if (isIndexable(iTyp)) {
        indexableElementOf[argName] ??= new Set<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.
        String argName0 = getConstName(iTyp.typeArguments[0].displayName);
        String argName1 = getConstName(iTyp.typeArguments[1].displayName);
        subscriptsTo[typName] = argName1;
        elementOf[argName1] ??= new Set<String>();
        elementOf[argName1].add(typName);
        indexableElementOf[argName1] ??= new Set<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.
  Set<InterfaceType> newITypes = new Set<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;
  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 true;
      }
      ParameterizedType ptx = pType.element.instantiate(
        typeArguments: [iType],
        nullabilitySuffix: NullabilitySuffix.star,
      );
      newITypes.add(ptx);
      if (iType.typeArguments.length >= 1) {
        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 true;
        }
        ParameterizedType ptx = pType.element.instantiate(
          typeArguments: [iType1, iType2],
          nullabilitySuffix: NullabilitySuffix.star,
        );
        newITypes.add(ptx);
        if (iType1.typeArguments.length >= 1 ||
            iType2.typeArguments.length >= 1) {
          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).
  Set<InterfaceType> pTypes1 = new Set<InterfaceType>();
  // Types with two parameters (Map).
  Set<InterfaceType> pTypes2 = new Set<InterfaceType>();
  // Types with no parameters or parameters of which have already been
  // instantiated.
  Set<InterfaceType> iTypes = new Set<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.
  Set<InterfaceType> filteredITypes = {};
  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 (int i = 0; i < depth + 1; ++i) {
    double mn = max(1, maxNew / (depth + 1));
    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) {
  int 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 (InterfaceType ci in ce.interfaces) {
      no += countOperators(ci.element);
    }
  });
  return no;
}

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

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

visitLibraryAtUri(
    AnalysisSession session, String uri, Set<InterfaceType> allTypes) async {
  String libPath = session.uriConverter.uriToPath(Uri.parse(uri));
  ResolvedLibraryResult result = await session.getResolvedLibrary(libPath);
  if (result.state != ResultState.VALID) {
    throw new StateError('Unable to resolve "$uri"');
  }
  visitLibrary(result.element, allTypes);
}

visitLibrary(LibraryElement library, Set<InterfaceType> allTypes) async {
  // 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 (CompilationUnitElement unit in library.units) {
    visitCompilationUnit(unit, allTypes);
  }
}

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 (ClassElement 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) {
  Set<String> iTypes = new Set<String>();
  for (InterfaceType iTyp in tp.interfaces) {
    String 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 (InterfaceType tp in allTypes) {
    String typName = getConstName(tp.displayName);
    for (String ifTypName in getInterfaces(tp)) {
      interfaceRels[ifTypName] ??= new Set<String>();
      interfaceRels[ifTypName].add(typName);
      if (ifTypName.contains('ITERABLE')) {
        iterableTypes1.add(typName);
      }
    }
    for (InterfaceType it in tp.element.allSupertypes) {
      String ifTypName = getConstName(it.displayName);
      interfaceRels[ifTypName] ??= new Set<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 (InterfaceType tp in allTypes) {
    String typName = getConstName(tp.displayName);
    if (interfaceRels.containsKey(typName)) {
      interfaceRels[typName].add(typName);
    }
  }
}

main(List<String> arguments) async {
  final parser = new 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');
  try {
    final results = parser.parse(arguments);
    int depth = int.parse(results['depth']);
    Set<InterfaceType> allTypes = new Set<InterfaceType>();
    // Filter types to instantiate parameterized types with, this excludes
    // complex types like Int8List (might be added later).
    Set<String> iTypeFilter = {'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);
  } catch (e) {
    print('Usage: dart gen_type_table.dart [OPTIONS]\n${parser.usage}\n$e');
    exitCode = 255;
  }
}
