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

import 'allocator.dart';
import 'base.dart';
import 'specs/class.dart';
import 'specs/code.dart';
import 'specs/constructor.dart';
import 'specs/control.dart';
import 'specs/directive.dart';
import 'specs/enum.dart';
import 'specs/expression.dart';
import 'specs/extension.dart';
import 'specs/extension_type.dart';
import 'specs/field.dart';
import 'specs/library.dart';
import 'specs/method.dart';
import 'specs/mixin.dart';
import 'specs/pattern.dart';
import 'specs/reference.dart';
import 'specs/type_function.dart';
import 'specs/type_record.dart';
import 'specs/type_reference.dart';
import 'specs/typedef.dart';
import 'visitors.dart';

/// Helper method improving on [StringSink.writeAll].
///
/// For every `Spec` in [elements], executing [visit].
///
/// If [elements] is at least 2 elements, inserts [separator] delimiting them.
StringSink visitAll<T>(
  Iterable<T> elements,
  StringSink output,
  void Function(T) visit, [
  String separator = ', ',
]) {
  // Basically, this whole method is an improvement on
  //   output.writeAll(specs.map((s) => s.accept(visitor));
  //
  // ... which would allocate more StringBuffer(s) for a one-time use.
  if (elements.isEmpty) {
    return output;
  }
  final iterator = elements.iterator..moveNext();
  visit(iterator.current);
  while (iterator.moveNext()) {
    output.write(separator);
    visit(iterator.current);
  }
  return output;
}

class DartEmitter extends Object
    with CodeEmitter, ExpressionEmitter, PatternEmitter, ControlEmitter
    implements SpecVisitor<StringSink> {
  @override
  final Allocator allocator;

  /// If directives should be ordered while emitting.
  ///
  /// Ordering rules follow the guidance in
  /// [Effective Dart](https://dart.dev/guides/language/effective-dart/style#ordering)
  /// and the
  /// [directives_ordering](https://dart-lang.github.io/linter/lints/directives_ordering.html)
  /// lint.
  final bool orderDirectives;

  /// If nullable types should be emitted with the nullable suffix ("?").
  ///
  /// Null safety syntax should only be enabled if the output will be used with
  /// a Dart language version which supports it.
  final bool _useNullSafetySyntax;

  /// Creates a new instance of [DartEmitter].
  ///
  /// May specify an [Allocator] to use for references and imports,
  /// otherwise uses [Allocator.none] which never prefixes references and will
  /// not automatically emit import directives.
  DartEmitter({
    this.allocator = Allocator.none,
    this.orderDirectives = false,
    bool useNullSafetySyntax = false,
  }) : _useNullSafetySyntax = useNullSafetySyntax;

  /// Creates a new instance of [DartEmitter] with simple automatic imports.
  factory DartEmitter.scoped({
    bool orderDirectives = false,
    bool useNullSafetySyntax = false,
  }) => DartEmitter(
    allocator: Allocator.simplePrefixing(),
    orderDirectives: orderDirectives,
    useNullSafetySyntax: useNullSafetySyntax,
  );

  static bool _isLambdaBody(Code? code) =>
      code is ToCodeExpression && !code.isStatement;

  /// Whether the provided [method] is considered a lambda method.
  static bool _isLambdaMethod(Method method) =>
      method.lambda ?? _isLambdaBody(method.body);

  /// Whether the provided [constructor] is considered a lambda method.
  static bool _isLambdaConstructor(Constructor constructor) =>
      constructor.lambda ??
      constructor.factory && _isLambdaBody(constructor.body);

  @override
  StringSink visitAnnotation(Expression spec, [StringSink? output]) {
    (output ??= StringBuffer()).write('@');
    spec.accept(this, output);
    output.write(' ');
    return output;
  }

  @override
  StringSink visitClass(Class spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }

    void writeModifier() {
      if (spec.modifier != null) {
        out.write('${spec.modifier!.name} ');
      }
    }

    if (spec.sealed) {
      out.write('sealed ');
    } else {
      if (spec.abstract) {
        out.write('abstract ');
      }
      writeModifier();
      if (spec.mixin) {
        out.write('mixin ');
      }
    }
    out.write('class ${spec.name}');
    visitTypeParameters(spec.types.map((r) => r.type), out);
    if (spec.extend != null) {
      out.write(' extends ');
      spec.extend!.type.accept(this, out);
    }
    if (spec.mixins.isNotEmpty) {
      out
        ..write(' with ')
        ..writeAll(
          spec.mixins.map<StringSink>((m) => m.type.accept(this)),
          ',',
        );
    }
    if (spec.implements.isNotEmpty) {
      out
        ..write(' implements ')
        ..writeAll(
          spec.implements.map<StringSink>((m) => m.type.accept(this)),
          ',',
        );
    }
    out.write(' {');
    for (var c in spec.constructors) {
      visitConstructor(c, spec.name, out);
      out.writeln();
    }
    for (var f in spec.fields) {
      visitField(f, out);
      out.writeln();
    }
    _visitMethods(spec.methods, out);
    out.writeln('}');
    return out;
  }

  @override
  StringSink visitMixin(Mixin spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }

    if (spec.base) {
      out.write('base ');
    }
    out.write('mixin ${spec.name}');
    visitTypeParameters(spec.types.map((r) => r.type), out);
    if (spec.onTypes.isNotEmpty) {
      out.write(' on ');
      visitAll<Reference>(spec.onTypes, out, (r) {
        r.type.accept(this, out);
      }, ',');
    } else if (spec.on != null) {
      out.write(' on ');
      spec.on!.type.accept(this, out);
    }
    if (spec.implements.isNotEmpty) {
      out
        ..write(' implements ')
        ..writeAll(
          spec.implements.map<StringSink>((m) => m.type.accept(this)),
          ',',
        );
    }
    out.write(' {');
    for (var f in spec.fields) {
      visitField(f, out);
      out.writeln();
    }
    _visitMethods(spec.methods, out);
    out.write('}');
    return out;
  }

  @override
  StringSink visitConstructor(
    Constructor spec,
    String clazz, [
    StringSink? output,
  ]) {
    output ??= StringBuffer();
    spec.docs.forEach(output.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, output);
    }
    if (spec.external) {
      output.write('external ');
    }
    if (spec.constant) {
      output.write('const ');
    }
    if (spec.factory) {
      output.write('factory ');
    }
    output.write(clazz);
    if (spec.name != null) {
      output
        ..write('.')
        ..write(spec.name);
    }
    output.write('(');
    final hasMultipleParameters =
        spec.requiredParameters.length + spec.optionalParameters.length > 1;
    if (spec.requiredParameters.isNotEmpty) {
      var count = 0;
      for (final p in spec.requiredParameters) {
        count++;
        _visitParameter(p, output);
        if (hasMultipleParameters ||
            spec.requiredParameters.length != count ||
            spec.optionalParameters.isNotEmpty) {
          output.write(', ');
        }
      }
    }
    if (spec.optionalParameters.isNotEmpty) {
      final named = spec.optionalParameters.any((p) => p.named);
      if (named) {
        output.write('{');
      } else {
        output.write('[');
      }
      var count = 0;
      for (final p in spec.optionalParameters) {
        count++;
        _visitParameter(p, output, optional: true, named: named);
        if (hasMultipleParameters || spec.optionalParameters.length != count) {
          output.write(', ');
        }
      }
      if (named) {
        output.write('}');
      } else {
        output.write(']');
      }
    }
    output.write(')');
    if (spec.initializers.isNotEmpty) {
      output.write(' : ');
      var count = 0;
      for (final initializer in spec.initializers) {
        count++;
        initializer.accept(this, output);
        if (count != spec.initializers.length) {
          output.write(', ');
        }
      }
    }
    if (spec.redirect != null) {
      output.write(' = ');
      spec.redirect!.type.accept(this, output);
      output.write(';');
    } else if (spec.body != null) {
      if (_isLambdaConstructor(spec)) {
        output.write(' => ');
        spec.body!.accept(this, output);
        output.write(';');
      } else {
        output.write(' {');
        spec.body!.accept(this, output);
        output.write('}');
      }
    } else {
      output.write(';');
    }
    output.writeln();
    return output;
  }

  @override
  StringSink visitExtension(Extension spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }

    out.write('extension');
    if (spec.name != null) {
      out.write(' ${spec.name}');
    }
    visitTypeParameters(spec.types.map((r) => r.type), out);
    if (spec.on != null) {
      out.write(' on ');
      spec.on!.type.accept(this, out);
    }
    out.write(' {');
    for (var f in spec.fields) {
      visitField(f, out);
      out.writeln();
    }
    _visitMethods(spec.methods, out);
    out.writeln('}');
    return out;
  }

  @override
  StringSink visitExtensionType(ExtensionType spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }

    out.write('extension type ');
    if (spec.constant) out.write('const ');
    out.write(spec.name);
    visitTypeParameters(spec.types.map((r) => r.type), out);
    if (spec.primaryConstructorName.isNotEmpty) {
      out.write('.${spec.primaryConstructorName}');
    }
    out.write('(');
    _visitRepresentationDeclaration(spec.representationDeclaration, out);
    out.write(')');

    if (spec.implements.isNotEmpty) {
      out
        ..write(' implements ')
        ..writeAll(
          spec.implements.map<StringSink>((m) => m.type.accept(this)),
          ',',
        );
    }

    out.writeln(' {');
    for (var c in spec.constructors) {
      visitConstructor(c, spec.name, out);
      out.writeln();
    }
    for (var f in spec.fields) {
      visitField(f, out);
      out.writeln();
    }
    _visitMethods(spec.methods, out);
    out.writeln('}');
    return out;
  }

  void _visitRepresentationDeclaration(
    RepresentationDeclaration spec,
    StringSink out,
  ) {
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }
    spec.declaredRepresentationType.accept(this, out);
    out.write(' ${spec.name}');
  }

  @override
  StringSink visitDirective(Directive spec, [StringSink? output]) {
    output ??= StringBuffer();
    switch (spec.type) {
      case DirectiveType.import:
        output.write('import ');
        break;
      case DirectiveType.export:
        output.write('export ');
        break;
      case DirectiveType.part:
        output.write('part ');
        break;
      case DirectiveType.partOf:
        output.write('part of ');
        break;
    }
    output.write("'${spec.url}'");
    if (spec.as != null) {
      if (spec.deferred) {
        output.write(' deferred ');
      }
      output.write(' as ${spec.as}');
    }
    if (spec.show.isNotEmpty) {
      output
        ..write(' show ')
        ..writeAll(spec.show, ', ');
    } else if (spec.hide.isNotEmpty) {
      output
        ..write(' hide ')
        ..writeAll(spec.hide, ', ');
    }
    output.write(';');
    return output;
  }

  @override
  StringSink visitField(Field spec, [StringSink? output]) {
    output ??= StringBuffer();
    spec.docs.forEach(output.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, output);
    }
    if (spec.external) {
      output.write('external ');
    }
    if (spec.static) {
      output.write('static ');
    }
    if (spec.late && _useNullSafetySyntax) {
      output.write('late ');
    }
    switch (spec.modifier) {
      case FieldModifier.var$:
        if (spec.type == null) {
          output.write('var ');
        }
        break;
      case FieldModifier.final$:
        output.write('final ');
        break;
      case FieldModifier.constant:
        output.write('const ');
        break;
    }
    if (spec.type != null) {
      spec.type!.type.accept(this, output);
      output.write(' ');
    }
    output.write(spec.name);
    if (spec.assignment != null) {
      output.write(' = ');
      startConstCode(spec.modifier == FieldModifier.constant, () {
        spec.assignment!.accept(this, output);
      });
    }
    output.writeln(';');
    return output;
  }

  @override
  StringSink visitLibrary(Library spec, [StringSink? output]) {
    output ??= StringBuffer();

    if (spec.comments.isNotEmpty) {
      spec.comments.map((line) => '// $line').forEach(output.writeln);
      output.writeln();
    }

    if (spec.generatedByComment != null) {
      output
        ..writeln('// ${spec.generatedByComment}')
        ..writeln();
    }

    // Process the body first in order to prime the allocators.
    final body = StringBuffer();
    for (final spec in spec.body) {
      spec.accept(this, body);
      if (spec is Method && _isLambdaMethod(spec)) {
        body.write(';');
      }
    }

    final header = StringBuffer();
    spec.docs.forEach(header.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, header);
    }
    if (spec.name != null) {
      header.write('library ${spec.name!};');
    } else if (spec.annotations.isNotEmpty || spec.docs.isNotEmpty) {
      // An explicit _unnamed_ library directive is only required if there are
      // annotations or doc comments on the library.
      header.write('library;');
    }

    final directives = <Directive>[...allocator.imports, ...spec.directives];

    if (orderDirectives) {
      directives.sort();
    }

    final ignores = [
      ...spec.ignoreForFile,
      if (directives.any((d) => d.as?.startsWith('_') ?? false))
        'no_leading_underscores_for_library_prefixes',
    ];

    if (ignores.isNotEmpty) {
      ignores.sort();
      const prefix = '// ignore_for_file: ';
      final lines = [StringBuffer(prefix)..write(ignores.first)];
      for (var ignore in ignores.skip(1)) {
        if (lines.last.length + 2 + ignore.length > 80) {
          lines.add(StringBuffer(prefix)..write(ignore));
        } else {
          lines.last
            ..write(', ')
            ..write(ignore);
        }
      }
      lines.forEach(output.writeln);
      output.writeln();
    }

    output.write(header);

    Directive? previous;
    for (final directive in directives) {
      if (_newLineBetween(orderDirectives, previous, directive)) {
        // Note: dartfmt handles creating new lines between directives.
        // 2 lines are written here. The first one comes after the previous
        // directive `;`, the second is the empty line.
        output
          ..writeln()
          ..writeln();
      }
      directive.accept(this, output);
      previous = directive;
    }
    output.write(body);
    return output;
  }

  @override
  StringSink visitFunctionType(FunctionType spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    if (spec.returnType != null) {
      spec.returnType!.accept(this, out);
      out.write(' ');
    }
    out.write('Function');
    if (spec.types.isNotEmpty) {
      out.write('<');
      visitAll<Reference>(spec.types, out, (spec) {
        spec.accept(this, out);
      });
      out.write('>');
    }
    out.write('(');
    final needsTrailingComma =
        spec.requiredParameters.length +
            spec.optionalParameters.length +
            spec.namedRequiredParameters.length +
            spec.namedParameters.length >
        1;
    visitAll<Reference>(spec.requiredParameters, out, (spec) {
      spec.accept(this, out);
    });
    final hasNamedParameters =
        spec.namedRequiredParameters.isNotEmpty ||
        spec.namedParameters.isNotEmpty;
    if (spec.requiredParameters.isNotEmpty &&
        (needsTrailingComma ||
            spec.optionalParameters.isNotEmpty ||
            hasNamedParameters)) {
      out.write(', ');
    }
    if (spec.optionalParameters.isNotEmpty) {
      out.write('[');
      visitAll<Reference>(spec.optionalParameters, out, (spec) {
        spec.accept(this, out);
      });
      if (needsTrailingComma) {
        out.write(', ');
      }
      out.write(']');
    } else if (hasNamedParameters) {
      out.write('{');
      visitAll<String>(spec.namedRequiredParameters.keys, out, (name) {
        out.write('required ');
        spec.namedRequiredParameters[name]!.accept(this, out);
        out
          ..write(' ')
          ..write(name);
      });
      if (spec.namedRequiredParameters.isNotEmpty &&
          spec.namedParameters.isNotEmpty) {
        out.write(', ');
      }
      visitAll<String>(spec.namedParameters.keys, out, (name) {
        spec.namedParameters[name]!.accept(this, out);
        out
          ..write(' ')
          ..write(name);
      });
      if (needsTrailingComma) {
        out.write(', ');
      }
      out.write('}');
    }
    out.write(')');
    if (_useNullSafetySyntax && (spec.isNullable ?? false)) {
      out.write('?');
    }
    return out;
  }

  @override
  StringSink visitRecordType(RecordType spec, [StringSink? output]) {
    final out = (output ??= StringBuffer())..write('(');
    visitAll<Reference>(spec.positionalFieldTypes, out, (spec) {
      spec.accept(this, out);
    });
    if (spec.namedFieldTypes.isNotEmpty) {
      if (spec.positionalFieldTypes.isNotEmpty) {
        out.write(', ');
      }
      out.write('{');
      visitAll<MapEntry<String, Reference>>(spec.namedFieldTypes.entries, out, (
        entry,
      ) {
        entry.value.accept(this, out);
        out.write(' ${entry.key}');
      });
      out.write('}');
    } else if (spec.positionalFieldTypes.length == 1) {
      out.write(',');
    }
    out.write(')');
    // It doesn't really make sense to use records without
    // `_useNullSafetySyntax`, but since code_builder is generally very
    // permissive, follow it here too.
    if (_useNullSafetySyntax && (spec.isNullable ?? false)) {
      out.write('?');
    }
    return out;
  }

  @override
  StringSink visitTypeDef(TypeDef spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }
    out.write('typedef ${spec.name}');
    visitTypeParameters(spec.types.map((r) => r.type), out);
    out.write(' = ');
    spec.definition.accept(this, out);
    out.writeln(';');
    return out;
  }

  @override
  StringSink visitMethod(Method spec, [StringSink? output]) {
    output ??= StringBuffer();
    spec.docs.forEach(output.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, output);
    }
    if (spec.external) {
      output.write('external ');
    }
    if (spec.static) {
      output.write('static ');
    }
    if (spec.returns != null) {
      spec.returns!.accept(this, output);
      output.write(' ');
    }
    if (spec.type == MethodType.getter) {
      output
        ..write('get ')
        ..write(spec.name);
    } else {
      if (spec.type == MethodType.setter) {
        output.write('set ');
      }
      if (spec.name != null) {
        output.write(spec.name);
      }
      visitTypeParameters(spec.types.map((r) => r.type), output);
      output.write('(');
      final hasMultipleParameters =
          spec.requiredParameters.length + spec.optionalParameters.length > 1;
      if (spec.requiredParameters.isNotEmpty) {
        var count = 0;
        for (final p in spec.requiredParameters) {
          count++;
          _visitParameter(p, output);
          if (hasMultipleParameters ||
              spec.requiredParameters.length != count ||
              spec.optionalParameters.isNotEmpty) {
            output.write(', ');
          }
        }
      }
      if (spec.optionalParameters.isNotEmpty) {
        final named = spec.optionalParameters.any((p) => p.named);
        if (named) {
          output.write('{');
        } else {
          output.write('[');
        }
        var count = 0;
        for (final p in spec.optionalParameters) {
          count++;
          _visitParameter(p, output, optional: true, named: named);
          if (hasMultipleParameters ||
              spec.optionalParameters.length != count) {
            output.write(', ');
          }
        }
        if (named) {
          output.write('}');
        } else {
          output.write(']');
        }
      }
      output.write(')');
    }
    if (spec.body != null) {
      if (spec.modifier != null) {
        switch (spec.modifier!) {
          case MethodModifier.async:
            output.write(' async');
            break;
          case MethodModifier.asyncStar:
            output.write(' async*');
            break;
          case MethodModifier.syncStar:
            output.write(' sync*');
            break;
        }
      }
      if (_isLambdaMethod(spec)) {
        output.write(' => ');
      } else {
        output.write(' {');
      }
      spec.body!.accept(this, output);
      if (!_isLambdaMethod(spec)) {
        output.write('}');
      }
    } else {
      output.write(';');
    }
    return output;
  }

  // Expose as a first-class visit function only if needed.
  void _visitParameter(
    Parameter spec,
    StringSink output, {
    bool optional = false,
    bool named = false,
  }) {
    spec.docs.forEach(output.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, output);
    }
    // The `required` keyword must precede the `covariant` keyword.
    if (spec.required) {
      output.write('required ');
    }
    if (spec.covariant) {
      output.write('covariant ');
    }
    if (spec.type != null) {
      spec.type!.type.accept(this, output);
      output.write(' ');
    }
    if (spec.toThis) {
      output.write('this.');
    }
    if (spec.toSuper) {
      output.write('super.');
    }
    output.write(spec.name);
    if (optional && spec.defaultTo != null) {
      output.write(' = ');
      spec.defaultTo!.accept(this, output);
    }
  }

  void _visitMethods(Iterable<Method> methods, StringSink out) {
    for (final m in methods) {
      visitMethod(m, out);
      if (_isLambdaMethod(m)) {
        out.writeln(';');
      }
      out.writeln();
    }
  }

  @override
  StringSink visitReference(Reference spec, [StringSink? output]) =>
      (output ??= StringBuffer())..write(allocator.allocate(spec));

  @override
  StringSink visitSpec(Spec spec, [StringSink? output]) =>
      spec.accept(this, output);

  @override
  StringSink visitType(TypeReference spec, [StringSink? output]) {
    output ??= StringBuffer();
    // Intentionally not .accept to avoid stack overflow.
    visitReference(spec, output);
    if (spec.bound != null) {
      output.write(' extends ');
      spec.bound!.type.accept(this, output);
    }
    visitTypeParameters(spec.types.map((r) => r.type), output);
    if (_useNullSafetySyntax && (spec.isNullable ?? false)) {
      output.write('?');
    }
    return output;
  }

  @override
  StringSink visitTypeParameters(
    Iterable<Reference> specs, [
    StringSink? output,
  ]) {
    output ??= StringBuffer();
    if (specs.isNotEmpty) {
      output
        ..write('<')
        ..writeAll(specs.map<StringSink>((s) => s.accept(this)), ',')
        ..write('>');
    }
    return output;
  }

  @override
  StringSink visitEnum(Enum spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }
    out.write('enum ${spec.name}');
    visitTypeParameters(spec.types.map((r) => r.type), out);
    if (spec.mixins.isNotEmpty) {
      out
        ..write(' with ')
        ..writeAll(
          spec.mixins.map<StringSink>((m) => m.type.accept(this)),
          ', ',
        );
    }
    if (spec.implements.isNotEmpty) {
      out
        ..write(' implements ')
        ..writeAll(
          spec.implements.map<StringSink>((m) => m.type.accept(this)),
          ', ',
        );
    }
    out.write(' {');
    for (var v in spec.values) {
      v.docs.forEach(out.writeln);
      for (var a in v.annotations) {
        visitAnnotation(a, out);
      }
      out.write(v.name);
      if (v.constructorName != null) {
        out.write('.${v.constructorName}');
      }
      visitTypeParameters(v.types.map((r) => r.type), out);
      final takesArguments =
          v.constructorName != null ||
          v.arguments.isNotEmpty ||
          v.namedArguments.isNotEmpty;
      if (takesArguments) {
        out.write('(');
      }
      if (v.arguments.isNotEmpty) {
        out.writeAll(
          v.arguments.map<StringSink>((arg) => arg.accept(this)),
          ', ',
        );
      }
      if (v.arguments.isNotEmpty && v.namedArguments.isNotEmpty) {
        out.write(', ');
      }
      visitAll<String>(v.namedArguments.keys, out, (name) {
        out
          ..write(name)
          ..write(': ');
        v.namedArguments[name]!.accept(this, out);
      });
      if (takesArguments) {
        out.write(')');
      }
      if (v != spec.values.last) {
        out.writeln(',');
      } else if (spec.constructors.isNotEmpty ||
          spec.fields.isNotEmpty ||
          spec.methods.isNotEmpty) {
        out.writeln(';');
      }
    }
    for (var c in spec.constructors) {
      visitConstructor(c, spec.name, out);
      out.writeln();
    }
    for (var f in spec.fields) {
      visitField(f, out);
      out.writeln();
    }
    _visitMethods(spec.methods, out);
    out.writeln('}');
    return out;
  }
}

/// Returns `true` if:
///
/// * [ordered] is `true`
/// * [a] is non-`null`
/// * If there should be an empty line before [b] if it's emitted after [a].
bool _newLineBetween(bool ordered, Directive? a, Directive? b) {
  if (!ordered) return false;
  if (a == null) return false;

  assert(b != null);

  // Put a line between imports and exports
  if (a.type != b!.type) return true;

  // Within exports, don't put in extra blank lines
  if (a.type == DirectiveType.export) {
    assert(b.type == DirectiveType.export);
    return false;
  }

  // Return `true` if the schemes for [a] and [b] are different
  return !Uri.parse(a.url).isScheme(Uri.parse(b.url).scheme);
}
