String prettyPrint()

in lib/src/pretty_print.dart [18:120]


String prettyPrint(Object? object, {int? maxLineLength, int? maxItems}) {
  String _prettyPrint(Object? object, int indent, Set<Object?> seen, bool top) {
    // If the object is a matcher, use its description.
    if (object is Matcher) {
      var description = StringDescription();
      object.describe(description);
      return '<$description>';
    }

    // Avoid looping infinitely on recursively-nested data structures.
    if (seen.contains(object)) return '(recursive)';
    seen = seen.union({object});
    String pp(Object? child) => _prettyPrint(child, indent + 2, seen, false);

    if (object is Iterable) {
      // Print the type name for non-List iterables.
      var type = object is List ? '' : _typeName(object) + ':';

      // Truncate the list of strings if it's longer than [maxItems].
      var strings = object.map(pp).toList();
      if (maxItems != null && strings.length > maxItems) {
        strings.replaceRange(maxItems - 1, strings.length, ['...']);
      }

      // If the printed string is short and doesn't contain a newline, print it
      // as a single line.
      var singleLine = "$type[${strings.join(', ')}]";
      if ((maxLineLength == null ||
              singleLine.length + indent <= maxLineLength) &&
          !singleLine.contains('\n')) {
        return singleLine;
      }

      // Otherwise, print each member on its own line.
      return '$type[\n' +
          strings.map((string) {
            return _indent(indent + 2) + string;
          }).join(',\n') +
          '\n' +
          _indent(indent) +
          ']';
    } else if (object is Map) {
      // Convert the contents of the map to string representations.
      var strings = object.keys.map((key) {
        return '${pp(key)}: ${pp(object[key])}';
      }).toList();

      // Truncate the list of strings if it's longer than [maxItems].
      if (maxItems != null && strings.length > maxItems) {
        strings.replaceRange(maxItems - 1, strings.length, ['...']);
      }

      // If the printed string is short and doesn't contain a newline, print it
      // as a single line.
      var singleLine = '{${strings.join(", ")}}';
      if ((maxLineLength == null ||
              singleLine.length + indent <= maxLineLength) &&
          !singleLine.contains('\n')) {
        return singleLine;
      }

      // Otherwise, print each key/value pair on its own line.
      return '{\n' +
          strings.map((string) {
            return _indent(indent + 2) + string;
          }).join(',\n') +
          '\n' +
          _indent(indent) +
          '}';
    } else if (object is String) {
      // Escape strings and print each line on its own line.
      var lines = object.split('\n');
      return "'" +
          lines.map(_escapeString).join("\\n'\n${_indent(indent + 2)}'") +
          "'";
    } else {
      var value = object.toString().replaceAll('\n', _indent(indent) + '\n');
      var defaultToString = value.startsWith('Instance of ');

      // If this is the top-level call to [prettyPrint], wrap the value on angle
      // brackets to set it apart visually.
      if (top) value = '<$value>';

      // Print the type of objects with custom [toString] methods. Primitive
      // objects and objects that don't implement a custom [toString] don't need
      // to have their types printed.
      if (object is num ||
          object is bool ||
          object is Function ||
          object is RegExp ||
          object is MapEntry ||
          object is Expando ||
          object == null ||
          defaultToString) {
        return value;
      } else {
        return '${_typeName(object)}:$value';
      }
    }
  }

  return _prettyPrint(object, 0, <Object?>{}, true);
}