visitLibrary method

  1. @override
StringSink visitLibrary(
  1. Library spec, [
  2. StringSink? output
])
inherited

Implementation

@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;
}