// 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 API tables used by DartFuzz. Automatically generating these
// tables is less error-prone than generating such tables by hand. Furthermore,
// it simplifies regenerating the table when the libraries change.
//
// Usage:
//   dart gen_api_table.dart > dartfuzz_api_table.dart
//
// Then send out modified dartfuzz_api_table.dart for review together
// with a modified dartfuzz.dart that increases the version.

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/type.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';

import 'gen_util.dart';

// Enum for different restrictions on parameters for library methods.
// none - No restriction on the corresponding parameter.
// small - Corresponding parameter should be a small value.
// This enum has an equivalent enum in the generated Dartfuzz API table.
enum Restriction { none, small }

// Class that represents Dart library methods.
//
// Proto is a list (of Strings that represent DartTypes) whose first element is
// the DartType of the receiver (DartType.VOID if none). The remaining elements
// are DartTypes of the parameters. The second element is DartType.VOID if there
// are no parameters.
// This class has an equivalent class in the generated Dartfuzz API table.
class DartLib {
  final String name;
  final List<String> proto;
  final List<Restriction>? restrictions;
  final bool isMethod;
  const DartLib(this.name, this.proto, this.restrictions, this.isMethod);
}

// Constants for strings corresponding to the DartType.
const abstractClassInstantiationErrorEncoding =
    'DartType.ABSTRACTCLASSINSTANTIATIONERROR';
const argumentErrorEncoding = 'DartType.ARGUMENTERROR';
const assertionErrorEncoding = 'DartType.ERROR';
const boolEncoding = 'DartType.BOOL';
const byteDataEncoding = 'DartType.BYTEDATA';
const castErrorEncoding = 'DartType.CASTERROR';
const concurrentModificationErrorEncoding =
    'DartType.CONCURRENTMODIFICATIONERROR';
const cyclicInitializationErrorEncoding = 'DartType.CYCLICINITIALIZATIONERROR';
const deprecatedEncoding = 'DartType.DEPRECATED';
const doubleEncoding = 'DartType.DOUBLE';
const endianEncoding = 'DartType.ENDIAN';
const errorEncoding = 'DartType.ERROR';
const exceptionEncoding = 'DartType.EXCEPTION';
const expandoDoubleEncoding = 'DartType.EXPANDO_DOUBLE';
const expandoIntEncoding = 'DartType.EXPANDO_INT';
const fallThroughErrorEncoding = 'DartType.FALLTHROUGHERROR';
const float32ListEncoding = 'DartType.FLOAT32LIST';
const float32x4Encoding = 'DartType.FLOAT32X4';
const float32x4ListEncoding = 'DartType.FLOAT32X4LIST';
const float64ListEncoding = 'DartType.FLOAT64LIST';
const float64x2Encoding = 'DartType.FLOAT64X2';
const float64x2ListEncoding = 'DartType.FLOAT64X2LIST';
const formatExceptionEncoding = 'DartType.FORMATEXCEPTION';
const indexErrorEncoding = 'DartType.INDEXERROR';
const int16ListEncoding = 'DartType.INT16LIST';
const int32ListEncoding = 'DartType.INT32LIST';
const int32x4Encoding = 'DartType.INT32X4';
const int32x4ListEncoding = 'DartType.INT32X4LIST';
const int64ListEncoding = 'DartType.INT64LIST';
const int8ListEncoding = 'DartType.INT8LIST';
const intEncoding = 'DartType.INT';
const integerDivisionByZeroExceptionEncoding =
    'DartType.INTEGERDIVISIONBYZEROEXCEPTION';
const listIntEncoding = 'DartType.LIST_INT';
const mapEntryIntStringEncoding = 'DartType.MAPENTRY_INT_STRING';
const mapIntStringEncoding = 'DartType.MAP_INT_STRING';
const nullEncoding = 'DartType.NULL';
const nullThrownErrorEncoding = 'DartType.NULLTHROWNERROR';
const numEncoding = 'DartType.NUM';
const provisionalEncoding = 'DartType.PROVISIONAL';
const rangeErrorEncoding = 'DartType.RANGEERROR';
const regExpEncoding = 'DartType.REGEXP';
const runeIteratorEncoding = 'DartType.RUNEITERATOR';
const runesEncoding = 'DartType.RUNES';
const setIntEncoding = 'DartType.SET_INT';
const stackOverflowErrorEncoding = 'DartType.STACKOVERFLOWERROR';
const stateErrorEncoding = 'DartType.STATEERROR';
const stringBufferEncoding = 'DartType.STRINGBUFFER';
const stringEncoding = 'DartType.STRING';
const symbolEncoding = 'DartType.SYMBOL';
const typeErrorEncoding = 'DartType.TYPEERROR';
const uint16ListEncoding = 'DartType.UINT16LIST';
const uint32ListEncoding = 'DartType.UINT32LIST';
const uint64ListEncoding = 'DartType.UINT64LIST';
const uint8ClampedListEncoding = 'DartType.UINT8CLAMPEDLIST';
const uint8ListEncoding = 'DartType.UINT8LIST';
const unimplementedErrorEncoding = 'DartType.UNIMPLEMENTEDERROR';
const unsupportedErrorEncoding = 'DartType.UNSUPPORTEDERROR';
const voidEncoding = 'DartType.VOID';

// Constants for the library methods lists' names in dart_api_table.dart.
final abstractClassInstantiationErrorLibs =
    'abstractClassInstantiationErrorLibs';
final argumentErrorLibs = 'argumentErrorLibs';
final assertionErrorLibs = 'assertionErrorLibs';
final boolLibs = 'boolLibs';
final byteDataLibs = 'byteDataLibs';
final castErrorLibs = 'castErrorLibs';
final concurrentModificationErrorLibs = 'concurrentModificationErrorLibs';
final cyclicInitializationErrorLibs = 'cyclicInitializationErrorLibs';
final deprecatedLibs = 'deprecatedLibs';
final doubleLibs = 'doubleLibs';
final endianLibs = 'endianLibs';
final errorLibs = 'errorLibs';
final exceptionLibs = 'exceptionLibs';
final expandoDoubleLibs = 'expandoDoubleLibs';
final expandoIntLibs = 'expandoIntLibs';
final fallThroughErrorLibs = 'fallThroughErrorLibs';
final float32ListLibs = 'float32ListLibs';
final float32x4Libs = 'float32x4Libs';
final float32x4ListLibs = 'float32x4ListLibs';
final float64ListLibs = 'float64ListLibs';
final float64x2Libs = 'float64x2Libs';
final float64x2ListLibs = 'float64x2ListLibs';
final formatExceptionLibs = 'formatExceptionLibs';
final indexErrorLibs = 'indexErrorLibs';
final int16ListLibs = 'int16ListLibs';
final int32ListLibs = 'int32ListLibs';
final int32x4Libs = 'int32x4Libs';
final int32x4ListLibs = 'int32x4ListLibs';
final int64ListLibs = 'int64ListLibs';
final int8ListLibs = 'int8ListLibs';
final intLibs = 'intLibs';
final integerDivisionByZeroExceptionLibs = 'integerDivisionByZeroExceptionLibs';
final listLibs = 'listLibs';
final mapEntryIntStringLibs = 'mapEntryIntStringLibs';
final mapLibs = 'mapLibs';
final nullLibs = 'nullLibs';
final nullThrownErrorLibs = 'nullThrownErrorLibs';
final numLibs = 'numLibs';
final provisionalLibs = 'provisionalLibs';
final rangeErrorLibs = 'rangeErrorLibs';
final regExpLibs = 'regExpLibs';
final runeIteratorLibs = 'runeIteratorLibs';
final runesLibs = 'runesLibs';
final setLibs = 'setLibs';
final stackOverflowErrorLibs = 'stackOverflowErrorLibs';
final stateErrorLibs = 'stateErrorLibs';
final stringBufferLibs = 'stringBufferLibs';
final stringLibs = 'stringLibs';
final symbolLibs = 'symbolLibs';
final typeErrorLibs = 'typeErrorLibs';
final uint16ListLibs = 'uint16ListLibs';
final uint32ListLibs = 'uint32ListLibs';
final uint64ListLibs = 'uint64ListLibs';
final uint8ClampedListLibs = 'uint8ClampedListLibs';
final uint8ListLibs = 'uint8ListLibs';
final unimplementedErrorLibs = 'unimplementedErrorLibs';
final unsupportedErrorLibs = 'unsupportedErrorLibs';
final voidLibs = 'voidLibs';

// Map from the DartType (string) to the name of the library methods list.
final Map<String, String> typeToLibraryMethodsListName = () {
  var encodings = <String, String>{
    abstractClassInstantiationErrorEncoding:
        abstractClassInstantiationErrorLibs,
    argumentErrorEncoding: argumentErrorLibs,
    assertionErrorEncoding: assertionErrorLibs,
    boolEncoding: boolLibs,
    byteDataEncoding: byteDataLibs,
    castErrorEncoding: castErrorLibs,
    concurrentModificationErrorEncoding: concurrentModificationErrorLibs,
    cyclicInitializationErrorEncoding: cyclicInitializationErrorLibs,
    deprecatedEncoding: deprecatedLibs,
    doubleEncoding: doubleLibs,
    endianEncoding: endianLibs,
    errorEncoding: errorLibs,
    exceptionEncoding: exceptionLibs,
    expandoDoubleEncoding: expandoDoubleLibs,
    expandoIntEncoding: expandoIntLibs,
    fallThroughErrorEncoding: fallThroughErrorLibs,
    float32ListEncoding: float32ListLibs,
    float32x4Encoding: float32x4Libs,
    float32x4ListEncoding: float32x4ListLibs,
    float64ListEncoding: float64ListLibs,
    float64x2Encoding: float64x2Libs,
    float64x2ListEncoding: float64x2ListLibs,
    formatExceptionEncoding: formatExceptionLibs,
    indexErrorEncoding: indexErrorLibs,
    int16ListEncoding: int16ListLibs,
    int32ListEncoding: int32ListLibs,
    int32x4Encoding: int32x4Libs,
    int32x4ListEncoding: int32x4ListLibs,
    int64ListEncoding: int64ListLibs,
    int8ListEncoding: int8ListLibs,
    intEncoding: intLibs,
    integerDivisionByZeroExceptionEncoding: integerDivisionByZeroExceptionLibs,
    listIntEncoding: listLibs,
    mapEntryIntStringEncoding: mapEntryIntStringLibs,
    mapIntStringEncoding: mapLibs,
    nullEncoding: nullLibs,
    nullThrownErrorEncoding: nullThrownErrorLibs,
    numEncoding: numLibs,
    provisionalEncoding: provisionalLibs,
    rangeErrorEncoding: rangeErrorLibs,
    regExpEncoding: regExpLibs,
    runeIteratorEncoding: runeIteratorLibs,
    runesEncoding: runesLibs,
    setIntEncoding: setLibs,
    stackOverflowErrorEncoding: stackOverflowErrorLibs,
    stateErrorEncoding: stateErrorLibs,
    stringBufferEncoding: stringBufferLibs,
    stringEncoding: stringLibs,
    symbolEncoding: symbolLibs,
    typeErrorEncoding: typeErrorLibs,
    uint16ListEncoding: uint16ListLibs,
    uint32ListEncoding: uint32ListLibs,
    uint64ListEncoding: uint64ListLibs,
    uint8ClampedListEncoding: uint8ClampedListLibs,
    uint8ListEncoding: uint8ListLibs,
    unimplementedErrorEncoding: unimplementedErrorLibs,
    unsupportedErrorEncoding: unsupportedErrorLibs,
    voidEncoding: voidLibs,
  };
  var result = <String, String>{};
  encodings.forEach((key, value) {
    result[key] = value;
    result[key + "_NULLABLE"] = value + "Nullable";
  });
  return result;
}();

// Map from return type encoding to list of recognized methods with that
// return type.
final Map<String, List<DartLib>> typeToLibraryMethodsList = () {
  var encodings = <String>[
    abstractClassInstantiationErrorEncoding,
    argumentErrorEncoding,
    assertionErrorEncoding,
    boolEncoding,
    byteDataEncoding,
    castErrorEncoding,
    concurrentModificationErrorEncoding,
    cyclicInitializationErrorEncoding,
    deprecatedEncoding,
    doubleEncoding,
    endianEncoding,
    errorEncoding,
    exceptionEncoding,
    expandoDoubleEncoding,
    expandoIntEncoding,
    fallThroughErrorEncoding,
    float32ListEncoding,
    float32x4Encoding,
    float32x4ListEncoding,
    float64ListEncoding,
    float64x2Encoding,
    float64x2ListEncoding,
    formatExceptionEncoding,
    indexErrorEncoding,
    int16ListEncoding,
    int32ListEncoding,
    int32x4Encoding,
    int32x4ListEncoding,
    int64ListEncoding,
    int8ListEncoding,
    intEncoding,
    integerDivisionByZeroExceptionEncoding,
    listIntEncoding,
    mapEntryIntStringEncoding,
    mapIntStringEncoding,
    nullEncoding,
    nullThrownErrorEncoding,
    numEncoding,
    provisionalEncoding,
    rangeErrorEncoding,
    regExpEncoding,
    runeIteratorEncoding,
    runesEncoding,
    setIntEncoding,
    stackOverflowErrorEncoding,
    stateErrorEncoding,
    stringBufferEncoding,
    stringEncoding,
    symbolEncoding,
    typeErrorEncoding,
    uint16ListEncoding,
    uint32ListEncoding,
    uint64ListEncoding,
    uint8ClampedListEncoding,
    uint8ListEncoding,
    unimplementedErrorEncoding,
    unsupportedErrorEncoding,
    voidEncoding,
  ];
  var result = <String, List<DartLib>>{};
  for (var encoding in encodings) {
    result[encoding] = <DartLib>[];
    result[encoding + "_NULLABLE"] = <DartLib>[];
  }
  return result;
}();

final typedDataFloatTypes = [
  float32ListEncoding,
  float32x4Encoding,
  float32x4ListEncoding,
  float64ListEncoding,
  float64x2Encoding,
  float64x2ListEncoding
];

void main() async {
  final session = GenUtil.createAnalysisSession();

  // Visit libraries for table generation.
  await visitLibraryAtUri(session, 'dart:async');
  await visitLibraryAtUri(session, 'dart:cli');
  await visitLibraryAtUri(session, 'dart:collection');
  await visitLibraryAtUri(session, 'dart:convert');
  await visitLibraryAtUri(session, 'dart:core');
  await visitLibraryAtUri(session, 'dart:io');
  await visitLibraryAtUri(session, 'dart:isolate');
  await visitLibraryAtUri(session, 'dart:math');
  await visitLibraryAtUri(session, 'dart:typed_data');

  // Generate the tables in a stand-alone Dart class.
  dumpHeader();
  dumpTypeToLibraryMethodMap();
  dumpTypedDataFloatTypes();
  for (var key in typeToLibraryMethodsList.keys.toList()..sort()) {
    if (typeToLibraryMethodsList[key]!.isNotEmpty) {
      // Only output library methods lists that are non-empty.
      dumpTable(
          typeToLibraryMethodsListName[key]!, typeToLibraryMethodsList[key]!);
    }
  }
  dumpFooter();
}

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

void visitLibrary(LibraryElement library) {
  // 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);
  }
}

void visitCompilationUnit(CompilationUnitElement unit) {
  // 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 variable in unit.topLevelVariables) {
    if (variable.isPublic) {
      addToTable(typeString(variable.type), variable.name,
          [voidEncoding, voidEncoding],
          isMethod: false);
    }
  }
  for (var function in unit.functions) {
    if (function.isPublic && !function.isOperator) {
      addToTable(typeString(function.returnType), function.name,
          protoString(null, function.parameters));
    }
  }
  for (var classElement in unit.types) {
    if (classElement.isPublic) {
      visitClass(classElement);
    }
  }
}

void visitClass(ClassElement classElement) {
  // Classes that cause too many false divergences.
  if (classElement.name == 'ProcessInfo' ||
      classElement.name == 'Platform' ||
      classElement.name.startsWith('FileSystem')) {
    return;
  }
  // Every class element contains elements for the members, viz. `methods` visits
  // methods, `fields` visits fields, `accessors` visits getters and setters, etc.
  // There are also accessors to get the superclass, mixins, interfaces, type
  // parameters, etc.
  for (var constructor in classElement.constructors) {
    if (constructor.isPublic &&
        constructor.isFactory &&
        constructor.name.isNotEmpty) {
      addToTable(
          typeString(classElement.thisType),
          '${classString(classElement)}.${constructor.name}',
          protoString(null, constructor.parameters));
    }
  }
  for (var method in classElement.methods) {
    if (method.isPublic && !method.isOperator) {
      if (method.isStatic) {
        addToTable(
            typeString(method.returnType),
            '${classString(classElement)}.${method.name}',
            protoString(null, method.parameters));
      } else {
        addToTable(typeString(method.returnType), method.name,
            protoString(classElement.thisType, method.parameters));
      }
    }
  }
  for (var accessor in classElement.accessors) {
    if (accessor.isPublic && accessor.isGetter) {
      var variable = accessor.variable;
      if (accessor.isStatic) {
        addToTable(
            typeString(variable.type),
            '${classElement.name}.${variable.name}',
            [voidEncoding, voidEncoding],
            isMethod: false);
      } else {
        addToTable(typeString(variable.type), variable.name,
            [typeString(classElement.thisType), voidEncoding],
            isMethod: false);
      }
    }
  }
}

// Function that returns the explicit class name.
String classString(ClassElement classElement) {
  switch (typeString(classElement.thisType)) {
    case setIntEncoding:
      return 'Set<int>';
    case listIntEncoding:
      return 'List<int>';
    case mapIntStringEncoding:
      return 'Map<int, String>';
    default:
      return classElement.name;
  }
}

// Types are represented by an instance of `DartType`. For classes, the type
// will be an instance of `InterfaceType`, which will provide access to the
// defining (class) element, as well as any type arguments.
String typeString(DartType type) {
  String result = typeStringHelper(type);
  if (result == "?") {
    return result;
  }
  if (type.nullabilitySuffix == NullabilitySuffix.none) {
    return result;
  }
  return result + "_NULLABLE";
}

String typeStringHelper(DartType type) {
  if (type.isDartCoreBool) {
    return boolEncoding;
  } else if (type.isDartCoreInt) {
    return intEncoding;
  } else if (type.isDartCoreDouble) {
    return doubleEncoding;
  } else if (type.isDartCoreString) {
    return stringEncoding;
  }
  // Supertypes or type parameters are specialized in a consistent manner.
  // TODO(ajcbik): inspect type structure semantically, not by display name
  //               and unify DartFuzz's DartType with analyzer DartType.
  switch (type.displayName) {
    case 'AbstractClassInstantiationError':
      return abstractClassInstantiationErrorEncoding;
    case 'ArgumentError':
      return argumentErrorEncoding;
    case 'AssertionError':
      return assertionErrorEncoding;
    case 'CastError':
      return castErrorEncoding;
    case 'ConcurrentModificationError':
      return concurrentModificationErrorEncoding;
    case 'CyclicInitializationError':
      return cyclicInitializationErrorEncoding;
    case 'Deprecated':
      return deprecatedEncoding;
    case 'E':
      return intEncoding;
    case 'Endian':
      return endianEncoding;
    case 'Error':
      return errorEncoding;
    case 'Exception':
      return exceptionEncoding;
    case 'Expando<double>':
      return expandoDoubleEncoding;
    case 'Expando<int>':
      return expandoIntEncoding;
    case 'FallThroughError':
      return fallThroughErrorEncoding;
    case 'Float32List':
      return float32ListEncoding;
    case 'Float32x4':
      return float32x4Encoding;
    case 'Float32x4List':
      return float32x4ListEncoding;
    case 'Float64List':
      return float64ListEncoding;
    case 'Float64x2':
      return float64x2Encoding;
    case 'Float64x2List':
      return float64x2ListEncoding;
    case 'FormatException':
      return formatExceptionEncoding;
    case 'IndexError':
      return indexErrorEncoding;
    case 'Int16List':
      return int16ListEncoding;
    case 'Int32List':
      return int32ListEncoding;
    case 'Int32x4':
      return int32x4Encoding;
    case 'Int32x4List':
      return int32x4ListEncoding;
    case 'Int64List':
      return int64ListEncoding;
    case 'Int8List':
      return int8ListEncoding;
    case 'IntegerDivisionByZeroException':
      return integerDivisionByZeroExceptionEncoding;
    case 'List':
    case 'List<E>':
    case 'List<Object>':
    case 'List<dynamic>':
    case 'List<int>':
      return listIntEncoding;
    case 'Map':
    case 'Map<K, V>':
    case 'Map<dynamic, dynamic>':
    case 'Map<int, String>':
      return mapIntStringEncoding;
    case 'MapEntry':
    case 'MapEntry<K, V>':
    case 'MapEntry<dynamic, dynamic>':
    case 'MapEntry<int, String>':
      return mapEntryIntStringEncoding;
    case 'Null':
      return nullEncoding;
    case 'NullThrownError':
      return nullThrownErrorEncoding;
    case 'Provisional':
      return provisionalEncoding;
    case 'RangeError':
      return rangeErrorEncoding;
    case 'RegExp':
      return regExpEncoding;
    case 'RuneIterator':
      return runeIteratorEncoding;
    case 'Runes':
      return runesEncoding;
    case 'Set':
    case 'Set<E>':
    case 'Set<Object>':
    case 'Set<dynamic>':
    case 'Set<int>':
      return setIntEncoding;
    case 'StackOverflowError':
      return stackOverflowErrorEncoding;
    case 'StateError':
      return stateErrorEncoding;
    case 'StringBuffer':
      return stringBufferEncoding;
    case 'Symbol':
      return symbolEncoding;
    case 'TypeError':
      return typeErrorEncoding;
    case 'Uint16List':
      return uint16ListEncoding;
    case 'Uint32List':
      return uint32ListEncoding;
    case 'Uint64List':
      return uint64ListEncoding;
    case 'Uint8ClampedList':
      return uint8ClampedListEncoding;
    case 'Uint8List':
      return uint8ListEncoding;
    case 'UnimplementedError':
      return unimplementedErrorEncoding;
    case 'UnsupportedError':
      return unsupportedErrorEncoding;
    case 'num':
      return doubleEncoding;
    case 'void':
      return voidEncoding;
  }
  return '?';
}

List<String> protoString(
    DartType? receiver, List<ParameterElement> parameters) {
  final proto = [receiver == null ? voidEncoding : typeString(receiver)];
  // Construct prototype for non-named parameters.
  for (var parameter in parameters) {
    if (!parameter.isNamed) {
      proto.add(typeString(parameter.type));
    }
  }
  // Use 'void' for an empty parameter list.
  proto.length == 1 ? proto.add(voidEncoding) : proto;
  return proto;
}

List<DartLib> getTable(String ret) => typeToLibraryMethodsList.containsKey(ret)
    ? typeToLibraryMethodsList[ret]!
    : throw ArgumentError('Invalid ret value: $ret');

void addToTable(String ret, String name, List<String> proto,
    {bool isMethod = true}) {
  // If any of the type representations equal a question
  // mark, this means that DartFuzz' type system cannot
  // deal with such an expression yet. So drop the entry.
  if (ret == '?' || proto.contains('?')) {
    return;
  }
  // Avoid the exit function and other functions that give false divergences.
  // Note: to prevent certain constructors from being emitted, update the
  // exclude list in `shouldFilterConstructor` in gen_type_table.dart and
  // regenerate the type table.
  if (name == 'exit' ||
      name == 'pid' ||
      name == 'hashCode' ||
      name == 'exitCode' ||
      // TODO(fizaaluthra): Enable reciprocal and reciprocalSqrt after we resolve
      // https://github.com/dart-lang/sdk/issues/39551
      name == 'reciprocal' ||
      name == 'reciprocalSqrt') {
    return;
  }

  List<Restriction>? restrictions;
  // Restrict parameters for a few hardcoded cases,
  // for example, to avoid excessive runtime or memory
  // allocation in the generated fuzzing program.
  if (name == 'padLeft' || name == 'padRight') {
    for (var i = 0; i < proto.length - 1; ++i) {
      if (proto[i] == intEncoding && proto[i + 1] == stringEncoding) {
        restrictions = List<Restriction>.filled(proto.length, Restriction.none);
        restrictions[i] = Restriction.small;
        restrictions[i + 1] = Restriction.small;
        break;
      }
    }
  } else if (name == 'List<int>.filled') {
    for (var i = 0; i < proto.length; ++i) {
      if (proto[i] == intEncoding) {
        restrictions = List<Restriction>.filled(proto.length, Restriction.none);
        restrictions[i] = Restriction.small;
        break;
      }
    }
  }
  // Add to table.
  getTable(ret).add(DartLib(name, proto, restrictions, isMethod));
  // Every non-nullable result is also a valid nullable result.
  if (!ret.endsWith("_NULLABLE")) {
    getTable("${ret}_NULLABLE")
        .add(DartLib(name, proto, restrictions, isMethod));
  }
}

void dumpHeader() {
  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.

/// NOTE: this code has been generated automatically.

import 'dartfuzz_type_table.dart';

/// Enum for different restrictions on parameters for library methods.
/// none - No restriction on the corresponding parameter.
/// small - Corresponding parameter should be a small value.
enum Restriction {
  none,
  small
}

/// Class that represents Dart library methods.
///
/// The invididual lists are organized by return type.
/// Proto is a list of DartTypes whose first element is the type of the
/// DartType of the receiver (DartType.VOID if none). The remaining elements are
/// DartTypes of the parameters. The second element is DartType.VOID if there
/// are no parameters.
class DartLib {
  final String name;
  final List<DartType> proto;
  final List<Restriction>? restrictions;
  final bool isMethod;
  const DartLib(this.name, this.proto, this.isMethod,
  {this.restrictions});
  Restriction getRestriction(int paramIndex) => (restrictions == null) ?
  Restriction.none : restrictions![paramIndex];
''');
}

void dumpTypeToLibraryMethodMap() {
  print('  static final typeToLibraryMethods = {');
  for (var key in typeToLibraryMethodsListName.keys.toList()..sort()) {
    if (typeToLibraryMethodsList[key]!.isNotEmpty) {
      // Only output a mapping from type to library methods list name for those
      // types that have a non-empty library methods list.
      print('    $key: ${typeToLibraryMethodsListName[key]},');
    }
  }
  print('  };');
}

void dumpTypedDataFloatTypes() {
  print('  static const typedDataFloatTypes = [');
  for (var type in typedDataFloatTypes) {
    print('    $type,');
  }
  print('  ];');
}

void dumpTable(String identifier, List<DartLib> table) {
  print('  static const $identifier = [');
  table.sort((a, b) => (a.name.compareTo(b.name) == 0)
      ? a.proto.join().compareTo(b.proto.join())
      : a.name.compareTo(b.name));
  table.forEach(
      (t) => print('    DartLib(\'${t.name}\', ${t.proto}, ${t.isMethod}'
          '${t.restrictions == null ? "" : ", "
              "restrictions: ${t.restrictions}"}),'));
  print('  ];');
}

void dumpFooter() {
  print('}');
}
