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

library kernel.ast_to_text;

import 'dart:core';
import 'dart:convert' show json;

import '../ast.dart';
import '../import_table.dart';
import '../src/text_util.dart';

abstract class Namer<T> {
  int index = 0;
  final Map<T, String> map = <T, String>{};

  String getName(T key) => map.putIfAbsent(key, () => '$prefix${++index}');

  String get prefix;
}

class NormalNamer<T> extends Namer<T> {
  @override
  final String prefix;

  NormalNamer(this.prefix);
}

class ConstantNamer extends RecursiveVisitor with Namer<Constant> {
  @override
  final String prefix;

  ConstantNamer(this.prefix);

  @override
  String getName(Constant constant) {
    if (!map.containsKey(constant)) {
      // When printing a non-fully linked kernel AST (i.e. some [Reference]s
      // are not bound) to text, we need to avoid dereferencing any
      // references.
      //
      // The normal visitor API causes references to be dereferenced in order
      // to call the `visit<name>(<name>)` / `visit<name>Reference(<name>)`.
      //
      // We therefore handle any subclass of [Constant] which has [Reference]s
      // specially here.
      //
      if (constant is InstanceConstant) {
        // Avoid visiting `InstanceConstant.classReference`.
        for (final Constant value in constant.fieldValues.values) {
          // Name everything in post-order visit of DAG.
          getName(value);
        }
      } else if (constant is StaticTearOffConstant) {
        // We only care about naming the constants themselves. [TearOffConstant]
        // has no Constant children.
        // Avoid visiting `TearOffConstant.procedureReference`.
      } else {
        // Name everything in post-order visit of DAG.
        constant.visitChildren(this);
      }
    }
    return super.getName(constant);
  }

  @override
  void defaultConstantReference(Constant constant) {
    getName(constant);
  }

  @override
  void defaultDartType(DartType type) {
    // No need to recurse into dart types, we only care about naming the
    // constants themselves.
  }
}

class Disambiguator<T, U> {
  final Map<T, String> namesT = <T, String>{};
  final Map<U, String> namesU = <U, String>{};
  final Set<String> usedNames = new Set<String>();

  String disambiguate(T? key1, U? key2, String proposeName()) {
    String getNewName() {
      String proposedName = proposeName();
      if (usedNames.add(proposedName)) return proposedName;
      int i = 2;
      while (!usedNames.add('$proposedName$i')) {
        ++i;
      }
      return '$proposedName$i';
    }

    if (key1 != null) {
      String? result = namesT[key1];
      if (result != null) return result;
      return namesT[key1] = getNewName();
    }
    if (key2 != null) {
      String? result = namesU[key2];
      if (result != null) return result;
      return namesU[key2] = getNewName();
    }
    throw "Cannot disambiguate";
  }
}

NameSystem globalDebuggingNames = new NameSystem();

String debugLibraryName(Library? node) {
  return node == null
      ? 'null'
      : node.name ?? globalDebuggingNames.nameLibrary(node);
}

String debugClassName(Class? node) {
  return node == null ? 'null' : node.name;
}

String debugQualifiedClassName(Class node) {
  return debugLibraryName(node.enclosingLibrary) + '::' + debugClassName(node);
}

String debugMemberName(Member node) {
  return node.name.text;
}

String debugQualifiedMemberName(Member node) {
  if (node.enclosingClass != null) {
    return debugQualifiedClassName(node.enclosingClass!) +
        '::' +
        debugMemberName(node);
  } else {
    return debugLibraryName(node.enclosingLibrary) +
        '::' +
        debugMemberName(node);
  }
}

String debugTypeParameterName(TypeParameter node) {
  return node.name ?? globalDebuggingNames.nameTypeParameter(node);
}

String debugQualifiedTypeParameterName(TypeParameter node) {
  TreeNode? parent = node.parent;
  if (parent is Class) {
    return debugQualifiedClassName(parent) +
        '::' +
        debugTypeParameterName(node);
  }
  if (parent is Member) {
    return debugQualifiedMemberName(parent) +
        '::' +
        debugTypeParameterName(node);
  }
  return debugTypeParameterName(node);
}

String debugVariableDeclarationName(VariableDeclaration node) {
  return node.name ?? globalDebuggingNames.nameVariable(node);
}

String debugNodeToString(Node node) {
  StringBuffer buffer = new StringBuffer();
  new Printer(buffer, syntheticNames: globalDebuggingNames).writeNode(node);
  return '$buffer';
}

String debugLibraryToString(Library library) {
  StringBuffer buffer = new StringBuffer();
  new Printer(buffer, syntheticNames: globalDebuggingNames)
      .writeLibraryFile(library);
  return '$buffer';
}

String debugComponentToString(Component component) {
  StringBuffer buffer = new StringBuffer();
  new Printer(buffer, syntheticNames: new NameSystem())
      .writeComponentFile(component);
  return '$buffer';
}

String componentToString(Component node) {
  StringBuffer buffer = new StringBuffer();
  new Printer(buffer, syntheticNames: new NameSystem())
      .writeComponentFile(node);
  return '$buffer';
}

class NameSystem {
  final Namer<VariableDeclaration> variables =
      new NormalNamer<VariableDeclaration>('#t');
  final Namer<Member> members = new NormalNamer<Member>('#m');
  final Namer<Class> classes = new NormalNamer<Class>('#class');
  final Namer<Extension> extensions = new NormalNamer<Extension>('#extension');
  final Namer<Library> libraries = new NormalNamer<Library>('#lib');
  final Namer<TypeParameter> typeParameters =
      new NormalNamer<TypeParameter>('#T');
  final Namer<TreeNode> labels = new NormalNamer<TreeNode>('#L');
  final Namer<Constant> constants = new ConstantNamer('#C');
  final Disambiguator<Reference, CanonicalName> prefixes =
      new Disambiguator<Reference, CanonicalName>();

  String nameVariable(VariableDeclaration node) => variables.getName(node);
  String nameMember(Member node) => members.getName(node);
  String nameClass(Class node) => classes.getName(node);
  String nameExtension(Extension node) => extensions.getName(node);
  String nameLibrary(Library node) => libraries.getName(node);
  String nameTypeParameter(TypeParameter node) => typeParameters.getName(node);
  String nameSwitchCase(SwitchCase node) => labels.getName(node);
  String nameLabeledStatement(LabeledStatement node) => labels.getName(node);
  String nameConstant(Constant node) => constants.getName(node);

  final RegExp pathSeparator = new RegExp('[\\/]');

  String nameLibraryPrefix(Library node, {String? proposedName}) {
    return prefixes.disambiguate(node.reference, node.reference.canonicalName,
        () {
      if (proposedName != null) {
        return proposedName;
      }
      String? name = node.name;
      if (name != null) {
        return abbreviateName(name);
      }
      // ignore: unnecessary_null_comparison
      if (node.importUri != null) {
        String path = node.importUri.hasEmptyPath
            ? '${node.importUri}'
            : node.importUri.pathSegments.last;
        if (path.endsWith('.dart')) {
          path = path.substring(0, path.length - '.dart'.length);
        }
        return abbreviateName(path);
      }
      return 'L';
    });
  }

  String nameCanonicalNameAsLibraryPrefix(Reference? node, CanonicalName? name,
      {String? proposedName}) {
    return prefixes.disambiguate(node, name, () {
      if (proposedName != null) return proposedName;
      CanonicalName? canonicalName = name ?? node?.canonicalName;
      if (canonicalName?.name != null) {
        String path = canonicalName!.name;
        int slash = path.lastIndexOf(pathSeparator);
        if (slash >= 0) {
          path = path.substring(slash + 1);
        }
        if (path.endsWith('.dart')) {
          path = path.substring(0, path.length - '.dart'.length);
        }
        return abbreviateName(path);
      }
      return 'L';
    });
  }

  final RegExp punctuation = new RegExp('[.:]');

  String abbreviateName(String name) {
    int dot = name.lastIndexOf(punctuation);
    if (dot != -1) {
      name = name.substring(dot + 1);
    }
    if (name.length > 4) {
      return name.substring(0, 3);
    }
    return name;
  }
}

abstract class Annotator {
  String annotateVariable(Printer printer, VariableDeclaration node);
  String annotateReturn(Printer printer, FunctionNode node);
  String annotateField(Printer printer, Field node);
}

/// A quick and dirty ambiguous text printer.
class Printer extends Visitor<void> with VisitorVoidMixin {
  final NameSystem syntheticNames;
  final StringSink sink;
  final Annotator? annotator;
  final Map<String, MetadataRepository<dynamic>>? metadata;
  ImportTable? importTable;
  int indentation = 0;
  int column = 0;
  bool showOffsets;
  bool showMetadata;

  static int SPACE = 0;
  static int WORD = 1;
  static int SYMBOL = 2;
  int state = SPACE;

  Printer(this.sink,
      {NameSystem? syntheticNames,
      this.showOffsets: false,
      this.showMetadata: false,
      this.importTable,
      this.annotator,
      this.metadata})
      : this.syntheticNames = syntheticNames ?? new NameSystem();

  Printer createInner(ImportTable importTable,
      Map<String, MetadataRepository<dynamic>>? metadata) {
    return new Printer(sink,
        importTable: importTable,
        metadata: metadata,
        syntheticNames: syntheticNames,
        annotator: annotator,
        showOffsets: showOffsets,
        showMetadata: showMetadata);
  }

  bool shouldHighlight(Node node) {
    return false;
  }

  void startHighlight(Node node) {}
  void endHighlight(Node node) {}

  String getLibraryName(Library node) {
    return node.name ?? syntheticNames.nameLibrary(node);
  }

  String getLibraryReference(Library node) {
    // ignore: unnecessary_null_comparison
    if (node == null) return '<No Library>';
    if (importTable != null && importTable?.getImportIndex(node) != -1) {
      return syntheticNames.nameLibraryPrefix(node);
    }
    return getLibraryName(node);
  }

  String getClassName(Class node) {
    return node.name;
  }

  String getExtensionName(Extension node) {
    return node.name;
  }

  String getClassReference(Class node) {
    // ignore: unnecessary_null_comparison
    if (node == null) return '<No Class>';
    String name = getClassName(node);
    String library = getLibraryReference(node.enclosingLibrary);
    return '$library::$name';
  }

  String getExtensionReference(Extension node) {
    // ignore: unnecessary_null_comparison
    if (node == null) return '<No Extension>';
    String name = getExtensionName(node);
    String library = getLibraryReference(node.enclosingLibrary);
    return '$library::$name';
  }

  String getTypedefReference(Typedef node) {
    // ignore: unnecessary_null_comparison
    if (node == null) return '<No Typedef>';
    String library = getLibraryReference(node.enclosingLibrary);
    return '$library::${node.name}';
  }

  static final String emptyNameString = '•';
  static final Name emptyName = new Name(emptyNameString);

  Name getMemberName(Member node) {
    if (node.name.text == '') return emptyName;
    // ignore: unnecessary_null_comparison
    if (node.name != null) return node.name;
    return new Name(syntheticNames.nameMember(node));
  }

  String getMemberReference(Member node) {
    // ignore: unnecessary_null_comparison
    if (node == null) return '<No Member>';
    String name = getMemberName(node).text;
    Class? enclosingClass = node.enclosingClass;
    if (enclosingClass != null) {
      String className = getClassReference(enclosingClass);
      return '$className::$name';
    } else {
      String library = getLibraryReference(node.enclosingLibrary);
      return '$library::$name';
    }
  }

  String getVariableName(VariableDeclaration node) {
    return node.name ?? syntheticNames.nameVariable(node);
  }

  String getVariableReference(VariableDeclaration node) {
    // ignore: unnecessary_null_comparison
    if (node == null) return '<No VariableDeclaration>';
    return getVariableName(node);
  }

  String getTypeParameterName(TypeParameter node) {
    return node.name ?? syntheticNames.nameTypeParameter(node);
  }

  String getTypeParameterReference(TypeParameter node) {
    // ignore: unnecessary_null_comparison
    if (node == null) return '<No TypeParameter>';
    String name = getTypeParameterName(node);
    TreeNode? parent = node.parent;
    if (parent is FunctionNode && parent.parent is Member) {
      String member = getMemberReference(parent.parent as Member);
      return '$member::$name';
    } else if (parent is Class) {
      String className = getClassReference(parent);
      return '$className::$name';
    } else {
      return name; // Bound inside a function type.
    }
  }

  void writeComponentProblems(Component component) {
    writeProblemsAsJson("Problems in component", component.problemsAsJson);
  }

  void writeProblemsAsJson(String header, List<String>? problemsAsJson) {
    if (problemsAsJson != null && problemsAsJson.isNotEmpty) {
      endLine("//");
      write("// ");
      write(header);
      endLine(":");
      endLine("//");
      for (String s in problemsAsJson) {
        Map<String, dynamic> decoded = json.decode(s);
        List<dynamic> plainTextFormatted =
            decoded["plainTextFormatted"] as List<dynamic>;
        List<String> lines = plainTextFormatted.join("\n").split("\n");
        for (int i = 0; i < lines.length; i++) {
          write("//");
          String trimmed = lines[i].trimRight();
          if (trimmed.isNotEmpty) write(" ");
          endLine(trimmed);
        }
        if (lines.isNotEmpty) endLine("//");
      }
    }
  }

  void writeLibraryFile(Library library) {
    writeAnnotationList(library.annotations);
    writeWord('library');
    String? name = library.name;
    if (name != null) {
      writeWord(name);
    }
    List<String> flags = [];
    if (library.isUnsupported) {
      flags.add('isUnsupported');
    }
    if (library.isNonNullableByDefault) {
      flags.add('isNonNullableByDefault');
    }
    if (flags.isNotEmpty) {
      writeWord('/*${flags.join(',')}*/');
    }
    endLine(';');

    LibraryImportTable imports = new LibraryImportTable(library);
    Printer inner = createInner(imports, library.enclosingComponent?.metadata);
    inner.writeStandardLibraryContent(library,
        outerPrinter: this, importsToPrint: imports);
  }

  void printLibraryImportTable(LibraryImportTable imports) {
    for (Library library in imports.importedLibraries) {
      String importPath = imports.getImportPath(library);
      if (importPath == "") {
        String prefix =
            syntheticNames.nameLibraryPrefix(library, proposedName: 'self');
        endLine('import self as $prefix;');
      } else {
        String prefix = syntheticNames.nameLibraryPrefix(library);
        endLine('import "$importPath" as $prefix;');
      }
    }
  }

  void writeStandardLibraryContent(Library library,
      {Printer? outerPrinter, LibraryImportTable? importsToPrint}) {
    outerPrinter ??= this;
    outerPrinter.writeProblemsAsJson(
        "Problems in library", library.problemsAsJson);

    if (importsToPrint != null) {
      outerPrinter.printLibraryImportTable(importsToPrint);
    }

    writeAdditionalExports(library.additionalExports);
    endLine();
    library.dependencies.forEach(writeNode);
    if (library.dependencies.isNotEmpty) endLine();
    library.parts.forEach(writeNode);
    library.typedefs.forEach(writeNode);
    library.classes.forEach(writeNode);
    library.extensions.forEach(writeNode);
    library.fields.forEach(writeNode);
    library.procedures.forEach(writeNode);
  }

  void writeAdditionalExports(List<Reference> additionalExports) {
    if (additionalExports.isEmpty) return;
    write('additionalExports = (');
    for (int i = 0; i < additionalExports.length; i++) {
      Reference reference = additionalExports[i];
      NamedNode? node = reference.node;
      if (node is Class) {
        Library nodeLibrary = node.enclosingLibrary;
        String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
        write(prefix + '::' + node.name);
      } else if (node is Extension) {
        Library nodeLibrary = node.enclosingLibrary;
        String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
        write(prefix + '::' + node.name);
      } else if (node is Field) {
        Library nodeLibrary = node.enclosingLibrary;
        String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
        write(prefix + '::' + node.name.text);
      } else if (node is Procedure) {
        Library nodeLibrary = node.enclosingLibrary;
        String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
        write(prefix + '::' + node.name.text);
      } else if (node is Typedef) {
        Library nodeLibrary = node.enclosingLibrary;
        String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
        write(prefix + '::' + node.name);
      } else if (reference.canonicalName != null) {
        write(reference.canonicalName.toString());
      } else {
        throw new UnimplementedError('${node.runtimeType}');
      }

      if (i + 1 == additionalExports.length) {
        endLine(")");
      } else {
        endLine(",");
        write("  ");
      }
    }
  }

  void writeComponentFile(Component component) {
    ImportTable imports = new ComponentImportTable(component);
    Printer inner = createInner(imports, component.metadata);
    writeWord('main');
    writeSpaced('=');
    inner.writeMemberReferenceFromReference(component.mainMethodName);
    endLine(';');
    if (showMetadata) {
      inner.writeMetadata(component);
    }
    writeComponentProblems(component);
    for (Library library in component.libraries) {
      if (showMetadata) {
        inner.writeMetadata(library);
      }
      writeAnnotationList(library.annotations);
      writeWord('library');
      String? name = library.name;
      if (name != null) {
        writeWord(name);
      }
      // ignore: unnecessary_null_comparison
      if (library.importUri != null) {
        writeSpaced('from');
        writeWord('"${library.importUri}"');
      }
      String prefix = syntheticNames.nameLibraryPrefix(library);
      writeSpaced('as');
      writeWord(prefix);
      endLine(' {');
      ++inner.indentation;

      inner.writeStandardLibraryContent(library);
      --inner.indentation;
      endLine('}');
    }
    writeConstantTable(component);
  }

  void writeConstantTable(Component component) {
    if (syntheticNames.constants.map.isEmpty) return;
    ImportTable imports = new ComponentImportTable(component);
    Printer inner = createInner(imports, component.metadata);
    writeWord('constants ');
    endLine(' {');
    ++inner.indentation;
    for (final Constant constant
        in syntheticNames.constants.map.keys.toList()) {
      inner.writeNode(constant);
    }
    --inner.indentation;
    endLine('}');
  }

  int getPrecedence(Expression node) {
    return Precedence.of(node);
  }

  void write(String string) {
    sink.write(string);
    column += string.length;
  }

  void writeSpace([String string = ' ']) {
    write(string);
    state = SPACE;
  }

  void ensureSpace() {
    if (state != SPACE) writeSpace();
  }

  void writeSymbol(String string) {
    write(string);
    state = SYMBOL;
  }

  void writeSpaced(String string) {
    ensureSpace();
    write(string);
    writeSpace();
  }

  void writeComma([String string = ',']) {
    write(string);
    writeSpace();
  }

  void writeWord(String string) {
    if (string.isEmpty) return;
    ensureWordBoundary();
    write(string);
    state = WORD;
  }

  void ensureWordBoundary() {
    if (state == WORD) {
      writeSpace();
    }
  }

  void writeIndentation() {
    writeSpace('  ' * indentation);
  }

  void writeNode(Node? node) {
    if (node == null) {
      writeSymbol("<Null>");
    } else {
      final bool highlight = shouldHighlight(node);
      if (highlight) {
        startHighlight(node);
      }

      if (showOffsets && node is TreeNode) {
        writeWord("[${node.fileOffset}]");
      }
      if (showMetadata && node is TreeNode) {
        writeMetadata(node);
      }

      node.accept(this);

      if (highlight) {
        endHighlight(node);
      }
    }
  }

  void writeMetadata(TreeNode node) {
    if (metadata != null) {
      for (MetadataRepository<dynamic> md in metadata!.values) {
        final dynamic nodeMetadata = md.mapping[node];
        if (nodeMetadata != null) {
          writeWord("[@${md.tag}=${nodeMetadata}]");
        }
      }
    }
  }

  void writeAnnotatedType(DartType type, String? annotation) {
    writeType(type);
    if (annotation != null) {
      write('/');
      write(annotation);
      state = WORD;
    }
  }

  void writeType(DartType type) {
    // ignore: unnecessary_null_comparison
    if (type == null) {
      write('<No DartType>');
    } else {
      type.accept(this);
    }
  }

  void writeOptionalType(DartType type) {
    // ignore: unnecessary_null_comparison
    if (type != null) {
      type.accept(this);
    }
  }

  @override
  void visitSupertype(Supertype type) {
    // ignore: unnecessary_null_comparison
    if (type == null) {
      write('<No Supertype>');
    } else {
      writeClassReferenceFromReference(type.className);
      if (type.typeArguments.isNotEmpty) {
        writeSymbol('<');
        writeList(type.typeArguments, writeType);
        writeSymbol('>');
      }
    }
  }

  @override
  void visitTypedefType(TypedefType type) {
    writeTypedefReference(type.typedefNode);
    if (type.typeArguments.isNotEmpty) {
      writeSymbol('<');
      writeList(type.typeArguments, writeType);
      writeSymbol('>');
    }
  }

  void writeModifier(bool isThere, String name) {
    if (isThere) {
      writeWord(name);
    }
  }

  void writeName(Name name) {
    if (name.text == '') {
      writeWord(emptyNameString);
    } else {
      writeWord(name.text); // TODO: write library name
    }
  }

  void endLine([String? string]) {
    if (string != null) {
      write(string);
    }
    write('\n');
    state = SPACE;
    column = 0;
  }

  void writeFunction(FunctionNode function,
      {name, List<Initializer>? initializers, bool terminateLine: true}) {
    if (name is String) {
      writeWord(name);
    } else if (name is Name) {
      writeName(name);
    } else {
      assert(name == null);
    }
    writeTypeParameterList(function.typeParameters);
    writeParameterList(function.positionalParameters, function.namedParameters,
        function.requiredParameterCount);
    writeReturnType(
        function.returnType, annotator?.annotateReturn(this, function));
    if (initializers != null && initializers.isNotEmpty) {
      endLine();
      ++indentation;
      writeIndentation();
      writeComma(':');
      writeList(initializers, writeNode);
      --indentation;
    }
    if (function.asyncMarker != AsyncMarker.Sync) {
      writeSpaced(getAsyncMarkerKeyword(function.asyncMarker));
    }
    if (function.dartAsyncMarker != AsyncMarker.Sync &&
        function.dartAsyncMarker != function.asyncMarker) {
      writeSpaced("/* originally");
      writeSpaced(getAsyncMarkerKeyword(function.dartAsyncMarker));
      writeSpaced("*/");
    }
    Statement? body = function.body;
    if (body != null) {
      writeFunctionBody(body, terminateLine: terminateLine);
    } else if (terminateLine) {
      endLine(';');
    } else {
      writeSymbol(';');
    }
  }

  String getAsyncMarkerKeyword(AsyncMarker marker) {
    switch (marker) {
      case AsyncMarker.Sync:
        return 'sync';
      case AsyncMarker.SyncStar:
        return 'sync*';
      case AsyncMarker.Async:
        return 'async';
      case AsyncMarker.AsyncStar:
        return 'async*';
      case AsyncMarker.SyncYielding:
        return 'yielding';
      default:
        return '<Invalid async marker: $marker>';
    }
  }

  void writeFunctionBody(Statement body, {bool terminateLine: true}) {
    if (body is Block && body.statements.isEmpty) {
      ensureSpace();
      writeSymbol('{}');
      state = WORD;
      if (terminateLine) {
        endLine();
      }
    } else if (body is Block) {
      ensureSpace();
      endLine('{');
      ++indentation;
      body.statements.forEach(writeNode);
      --indentation;
      writeIndentation();
      writeSymbol('}');
      state = WORD;
      if (terminateLine) {
        endLine();
      }
    } else if (body is ReturnStatement && !terminateLine) {
      writeSpaced('=>');
      writeExpression(body.expression!);
    } else {
      writeBody(body);
    }
  }

  void writeFunctionType(FunctionType node,
      {List<VariableDeclaration>? typedefPositional,
      List<VariableDeclaration>? typedefNamed}) {
    if (state == WORD) {
      ensureSpace();
    }
    writeTypeParameterList(node.typeParameters);
    writeSymbol('(');
    List<DartType> positional = node.positionalParameters;

    bool parametersAnnotated = false;
    if (typedefPositional != null) {
      for (VariableDeclaration formal in typedefPositional) {
        parametersAnnotated =
            parametersAnnotated || formal.annotations.length > 0;
      }
    }
    if (typedefNamed != null) {
      for (VariableDeclaration formal in typedefNamed) {
        parametersAnnotated =
            parametersAnnotated || formal.annotations.length > 0;
      }
    }

    if (parametersAnnotated && typedefPositional != null) {
      writeList(typedefPositional.take(node.requiredParameterCount),
          writeVariableDeclaration);
    } else {
      writeList(positional.take(node.requiredParameterCount), writeType);
    }

    if (node.requiredParameterCount < positional.length) {
      if (node.requiredParameterCount > 0) {
        writeComma();
      }
      writeSymbol('[');
      if (parametersAnnotated && typedefPositional != null) {
        writeList(typedefPositional.skip(node.requiredParameterCount),
            writeVariableDeclaration);
      } else {
        writeList(positional.skip(node.requiredParameterCount), writeType);
      }
      writeSymbol(']');
    }
    if (node.namedParameters.isNotEmpty) {
      if (node.positionalParameters.isNotEmpty) {
        writeComma();
      }
      writeSymbol('{');
      if (parametersAnnotated && typedefNamed != null) {
        writeList(typedefNamed, writeVariableDeclaration);
      } else {
        writeList(node.namedParameters, visitNamedType);
      }
      writeSymbol('}');
    }
    writeSymbol(')');
    ensureSpace();
    write('→');
    writeNullability(node.nullability);
    writeSpace();
    writeType(node.returnType);
  }

  void writeBody(Statement body) {
    if (body is Block) {
      endLine(' {');
      ++indentation;
      body.statements.forEach(writeNode);
      --indentation;
      writeIndentation();
      endLine('}');
    } else {
      endLine();
      ++indentation;
      writeNode(body);
      --indentation;
    }
  }

  void writeReturnType(DartType type, String? annotation) {
    // ignore: unnecessary_null_comparison
    if (type == null) return;
    writeSpaced('→');
    writeAnnotatedType(type, annotation);
  }

  void writeTypeParameterList(List<TypeParameter> typeParameters) {
    if (typeParameters.isEmpty) return;
    writeSymbol('<');
    writeList(typeParameters, writeNode);
    writeSymbol('>');
    state = WORD; // Ensure space if not followed by another symbol.
  }

  void writeParameterList(List<VariableDeclaration> positional,
      List<VariableDeclaration> named, int requiredParameterCount) {
    writeSymbol('(');
    writeList(
        positional.take(requiredParameterCount), writeVariableDeclaration);
    if (requiredParameterCount < positional.length) {
      if (requiredParameterCount > 0) {
        writeComma();
      }
      writeSymbol('[');
      writeList(
          positional.skip(requiredParameterCount), writeVariableDeclaration);
      writeSymbol(']');
    }
    if (named.isNotEmpty) {
      if (positional.isNotEmpty) {
        writeComma();
      }
      writeSymbol('{');
      writeList(named, writeVariableDeclaration);
      writeSymbol('}');
    }
    writeSymbol(')');
  }

  void writeList<T>(Iterable<T> nodes, void callback(T x),
      {String separator: ','}) {
    bool first = true;
    for (T node in nodes) {
      if (first) {
        first = false;
      } else {
        writeComma(separator);
      }
      callback(node);
    }
  }

  void writeClassReferenceFromReference(Reference reference) {
    writeWord(getClassReferenceFromReference(reference));
  }

  String getClassReferenceFromReference(Reference reference) {
    // ignore: unnecessary_null_comparison
    if (reference == null) return '<No Class>';
    if (reference.node != null) return getClassReference(reference.asClass);
    if (reference.canonicalName != null) {
      return getCanonicalNameString(reference.canonicalName!);
    }
    throw "Neither node nor canonical name found";
  }

  void writeExtensionReferenceFromReference(Reference reference) {
    writeWord(getExtensionReferenceFromReference(reference));
  }

  String getExtensionReferenceFromReference(Reference reference) {
    // ignore: unnecessary_null_comparison
    if (reference == null) return '<No Extension>';
    if (reference.node != null) {
      return getExtensionReference(reference.asExtension);
    }
    if (reference.canonicalName != null) {
      return getCanonicalNameString(reference.canonicalName!);
    }
    throw "Neither node nor canonical name found";
  }

  void writeMemberReferenceFromReference(Reference? reference) {
    writeWord(getMemberReferenceFromReference(reference));
  }

  String getMemberReferenceFromReference(Reference? reference) {
    if (reference == null) return '<No Member>';
    if (reference.node != null) return getMemberReference(reference.asMember);
    if (reference.canonicalName != null) {
      return getCanonicalNameString(reference.canonicalName!);
    }
    throw "Neither node nor canonical name found";
  }

  String getCanonicalNameString(CanonicalName name) {
    if (name.isRoot) throw 'unexpected root';
    if (name.name.startsWith('@')) throw 'unexpected @';

    String libraryString(CanonicalName lib) {
      if (lib.reference.node != null) {
        return getLibraryReference(lib.reference.asLibrary);
      }
      return syntheticNames.nameCanonicalNameAsLibraryPrefix(
          lib.reference, lib);
    }

    String classString(CanonicalName cls) =>
        libraryString(cls.parent!) + '::' + cls.name;

    if (name.parent!.isRoot) return libraryString(name);
    if (name.parent!.parent!.isRoot) return classString(name);

    CanonicalName atNode = name.parent!;
    while (!atNode.name.startsWith('@')) {
      atNode = atNode.parent!;
    }

    String parent = "";
    if (atNode.parent!.parent!.isRoot) {
      parent = libraryString(atNode.parent!);
    } else {
      parent = classString(atNode.parent!);
    }

    if (name.name == '') return "$parent::$emptyNameString";
    return "$parent::${name.name}";
  }

  void writeTypedefReference(Typedef typedefNode) {
    writeWord(getTypedefReference(typedefNode));
  }

  void writeVariableReference(VariableDeclaration variable) {
    final bool highlight = shouldHighlight(variable);
    if (highlight) {
      startHighlight(variable);
    }
    writeWord(getVariableReference(variable));
    if (highlight) {
      endHighlight(variable);
    }
  }

  void writeTypeParameterReference(TypeParameter node) {
    writeWord(getTypeParameterReference(node));
  }

  void writeExpression(Expression node, [int? minimumPrecedence]) {
    final bool highlight = shouldHighlight(node);
    if (highlight) {
      startHighlight(node);
    }
    if (showOffsets) writeWord("[${node.fileOffset}]");
    bool needsParenteses = false;
    if (minimumPrecedence != null && getPrecedence(node) < minimumPrecedence) {
      needsParenteses = true;
      writeSymbol('(');
    }
    writeNode(node);
    if (needsParenteses) {
      writeSymbol(')');
    }
    if (highlight) {
      endHighlight(node);
    }
  }

  void writeAnnotation(Expression node) {
    writeSymbol('@');
    if (node is ConstructorInvocation) {
      writeMemberReferenceFromReference(node.targetReference);
      visitArguments(node.arguments);
    } else {
      writeExpression(node);
    }
  }

  void writeAnnotationList(List<Expression> nodes, {bool separateLines: true}) {
    for (Expression node in nodes) {
      if (separateLines) {
        writeIndentation();
      }
      writeAnnotation(node);
      if (separateLines) {
        endLine();
      } else {
        writeSpace();
      }
    }
  }

  @override
  void visitLibrary(Library node) {}

  @override
  void visitField(Field node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeModifier(node.isLate, 'late');
    writeModifier(node.isStatic, 'static');
    writeModifier(node.isCovariantByDeclaration, 'covariant-by-declaration');
    writeModifier(node.isCovariantByClass, 'covariant-by-class');
    writeModifier(node.isFinal, 'final');
    writeModifier(node.isConst, 'const');
    // Only show implicit getter/setter modifiers in cases where they are
    // out of the ordinary.
    if (node.isFinal) {
      writeModifier(node.hasSetter, '[setter]');
    }
    writeWord('field');
    writeSpace();
    writeAnnotatedType(node.type, annotator?.annotateField(this, node));
    writeName(getMemberName(node));
    Expression? initializer = node.initializer;
    if (initializer != null) {
      writeSpaced('=');
      writeExpression(initializer);
    }
    List<String> features = <String>[];
    if (node.enclosingLibrary.isNonNullableByDefault !=
        node.isNonNullableByDefault) {
      if (node.isNonNullableByDefault) {
        features.add("isNonNullableByDefault");
      } else {
        features.add("isLegacy");
      }
    }
    Class? enclosingClass = node.enclosingClass;
    if ((enclosingClass == null &&
            node.enclosingLibrary.fileUri != node.fileUri) ||
        (enclosingClass != null && enclosingClass.fileUri != node.fileUri)) {
      features.add(" from ${node.fileUri} ");
    }
    if (features.isNotEmpty) {
      writeWord("/*${features.join(',')}*/");
    }
    endLine(';');
  }

  @override
  void visitProcedure(Procedure node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeModifier(node.isExternal, 'external');
    writeModifier(node.isStatic, 'static');
    writeModifier(node.isAbstract, 'abstract');
    writeModifier(node.isForwardingStub, 'forwarding-stub');
    writeModifier(node.isForwardingSemiStub, 'forwarding-semi-stub');
    switch (node.stubKind) {
      case ProcedureStubKind.Regular:
      case ProcedureStubKind.AbstractForwardingStub:
      case ProcedureStubKind.ConcreteForwardingStub:
        break;
      case ProcedureStubKind.NoSuchMethodForwarder:
        writeWord('no-such-method-forwarder');
        break;
      case ProcedureStubKind.MemberSignature:
        writeWord('member-signature');
        break;
      case ProcedureStubKind.AbstractMixinStub:
        writeWord('mixin-stub');
        break;
      case ProcedureStubKind.ConcreteMixinStub:
        writeWord('mixin-super-stub');
        break;
    }
    writeWord(procedureKindToString(node.kind));
    List<String> features = <String>[];
    if (node.enclosingLibrary.isNonNullableByDefault !=
        node.isNonNullableByDefault) {
      if (node.isNonNullableByDefault) {
        features.add("isNonNullableByDefault");
      } else {
        features.add("isLegacy");
      }
    }
    Class? enclosingClass = node.enclosingClass;
    if ((enclosingClass == null &&
            node.enclosingLibrary.fileUri != node.fileUri) ||
        (enclosingClass != null && enclosingClass.fileUri != node.fileUri)) {
      features.add(" from ${node.fileUri} ");
    }
    if (features.isNotEmpty) {
      writeWord("/*${features.join(',')}*/");
    }
    if (node.signatureType != null) {
      writeWord('/* signature-type:');
      writeType(node.signatureType!);
      writeWord('*/');
    }
    switch (node.stubKind) {
      case ProcedureStubKind.Regular:
      case ProcedureStubKind.AbstractForwardingStub:
      case ProcedureStubKind.ConcreteForwardingStub:
      case ProcedureStubKind.NoSuchMethodForwarder:
      case ProcedureStubKind.ConcreteMixinStub:
        writeFunction(node.function, name: getMemberName(node));
        break;
      case ProcedureStubKind.MemberSignature:
      case ProcedureStubKind.AbstractMixinStub:
        writeFunction(node.function,
            name: getMemberName(node), terminateLine: false);
        if (node.function.body is ReturnStatement) {
          writeSymbol(';');
        }
        writeSymbol(' -> ');
        writeMemberReferenceFromReference(node.stubTargetReference!);
        endLine();
        break;
    }
  }

  @override
  void visitConstructor(Constructor node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeModifier(node.isExternal, 'external');
    writeModifier(node.isConst, 'const');
    writeModifier(node.isSynthetic, 'synthetic');
    writeWord('constructor');
    List<String> features = <String>[];
    if (node.enclosingLibrary.isNonNullableByDefault !=
        node.isNonNullableByDefault) {
      if (node.isNonNullableByDefault) {
        features.add("isNonNullableByDefault");
      } else {
        features.add("isLegacy");
      }
    }
    if (features.isNotEmpty) {
      writeWord("/*${features.join(',')}*/");
    }
    writeFunction(node.function,
        name: node.name, initializers: node.initializers);
  }

  @override
  void visitRedirectingFactory(RedirectingFactory node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeModifier(node.isExternal, 'external');
    writeModifier(node.isConst, 'const');
    writeWord('redirecting_factory');
    writeFunction(node.function, name: node.name);
    writeSpaced('=');
    writeMemberReferenceFromReference(node.targetReference!);
    if (node.typeArguments.isNotEmpty) {
      writeSymbol('<');
      writeList(node.typeArguments, writeType);
      writeSymbol('>');
    }
    List<String> features = <String>[];
    if (node.enclosingLibrary.isNonNullableByDefault !=
        node.isNonNullableByDefault) {
      if (node.isNonNullableByDefault) {
        features.add("isNonNullableByDefault");
      } else {
        features.add("isLegacy");
      }
    }
    if (features.isNotEmpty) {
      writeWord("/*${features.join(',')}*/");
    }
    endLine(';');
  }

  @override
  void visitClass(Class node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeModifier(node.isAbstract, 'abstract');
    writeModifier(node.isMacro, 'macro');
    writeWord('class');
    writeWord(getClassName(node));
    writeTypeParameterList(node.typeParameters);
    if (node.isMixinApplication) {
      writeSpaced('=');
      visitSupertype(node.supertype!);
      writeSpaced('with');
      visitSupertype(node.mixedInType!);
    } else if (node.supertype != null) {
      writeSpaced('extends');
      visitSupertype(node.supertype!);
    }
    if (node.implementedTypes.isNotEmpty) {
      writeSpaced('implements');
      writeList(node.implementedTypes, visitSupertype);
    }
    List<String> features = <String>[];
    if (node.isEnum) {
      features.add('isEnum');
    }
    if (node.isAnonymousMixin) {
      features.add('isAnonymousMixin');
    }
    if (node.isEliminatedMixin) {
      features.add('isEliminatedMixin');
    }
    if (node.isMixinDeclaration) {
      features.add('isMixinDeclaration');
    }
    if (node.hasConstConstructor) {
      features.add('hasConstConstructor');
    }
    if (features.isNotEmpty) {
      writeSpaced('/*${features.join(',')}*/');
    }
    String endLineString = ' {';
    if (node.enclosingLibrary.fileUri != node.fileUri) {
      endLineString += ' // from ${node.fileUri}';
    }
    endLine(endLineString);
    ++indentation;
    node.fields.forEach(writeNode);
    node.constructors.forEach(writeNode);
    node.procedures.forEach(writeNode);
    node.redirectingFactories.forEach(writeNode);
    --indentation;
    writeIndentation();
    endLine('}');
  }

  @override
  void visitExtension(Extension node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeWord('extension');
    if (node.isExtensionTypeDeclaration) {
      writeWord('type');
    }
    writeWord(getExtensionName(node));
    writeTypeParameterList(node.typeParameters);
    writeSpaced('on');
    writeType(node.onType);

    ExtensionTypeShowHideClause? showHideClause = node.showHideClause;
    if (showHideClause != null) {
      // 'Show' clause elements.
      if (showHideClause.shownSupertypes.isNotEmpty) {
        writeSpaced('show-types');
        writeList(showHideClause.shownSupertypes, visitSupertype);
      }
      if (showHideClause.shownMethods.isNotEmpty) {
        writeSpaced('show-methods');
        writeList(
            showHideClause.shownMethods, writeMemberReferenceFromReference);
      }
      if (showHideClause.shownGetters.isNotEmpty) {
        writeSpaced('show-getters');
        writeList(
            showHideClause.shownGetters, writeMemberReferenceFromReference);
      }
      if (showHideClause.shownSetters.isNotEmpty) {
        writeSpaced('show-setters');
        writeList(
            showHideClause.shownSetters, writeMemberReferenceFromReference);
      }
      if (showHideClause.shownOperators.isNotEmpty) {
        writeSpaced('show-operators');
        writeList(
            showHideClause.shownOperators, writeMemberReferenceFromReference);
      }

      // 'Hide' clause elements.
      if (showHideClause.hiddenSupertypes.isNotEmpty) {
        writeSpaced('hide-types');
        writeList(showHideClause.hiddenSupertypes, visitSupertype);
      }
      if (showHideClause.hiddenMethods.isNotEmpty) {
        writeSpaced('hide-methods');
        writeList(
            showHideClause.hiddenMethods, writeMemberReferenceFromReference);
      }
      if (showHideClause.hiddenGetters.isNotEmpty) {
        writeSpaced('hide-getters');
        writeList(
            showHideClause.hiddenGetters, writeMemberReferenceFromReference);
      }
      if (showHideClause.hiddenSetters.isNotEmpty) {
        writeSpaced('hide-setters');
        writeList(
            showHideClause.hiddenSetters, writeMemberReferenceFromReference);
      }
      if (showHideClause.hiddenOperators.isNotEmpty) {
        writeSpaced('hide-operators');
        writeList(
            showHideClause.hiddenOperators, writeMemberReferenceFromReference);
      }
    }

    String endLineString = ' {';
    if (node.enclosingLibrary.fileUri != node.fileUri) {
      endLineString += ' // from ${node.fileUri}';
    }

    endLine(endLineString);
    ++indentation;
    node.members.forEach((ExtensionMemberDescriptor descriptor) {
      writeIndentation();
      writeModifier(descriptor.isStatic, 'static');
      switch (descriptor.kind) {
        case ExtensionMemberKind.Method:
          writeWord('method');
          break;
        case ExtensionMemberKind.Getter:
          writeWord('get');
          break;
        case ExtensionMemberKind.Setter:
          writeWord('set');
          break;
        case ExtensionMemberKind.Operator:
          writeWord('operator');
          break;
        case ExtensionMemberKind.Field:
          writeWord('field');
          break;
        case ExtensionMemberKind.TearOff:
          writeWord('tearoff');
          break;
      }
      writeName(descriptor.name);
      writeSpaced('=');
      Member member = descriptor.member.asMember;
      if (member is Procedure) {
        if (member.isGetter) {
          writeWord('get');
        } else if (member.isSetter) {
          writeWord('set');
        }
      }
      writeMemberReferenceFromReference(descriptor.member);
      endLine(';');
    });
    --indentation;
    writeIndentation();
    endLine('}');
  }

  @override
  void visitTypedef(Typedef node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeWord('typedef');
    writeWord(node.name);
    writeTypeParameterList(node.typeParameters);
    writeSpaced('=');
    DartType? type = node.type;
    if (type is FunctionType) {
      writeFunctionType(type,
          typedefPositional: node.positionalParameters,
          typedefNamed: node.namedParameters);
    } else {
      writeNode(type);
    }
    endLine(';');
  }

  @override
  void visitInvalidExpression(InvalidExpression node) {
    writeWord('invalid-expression');
    if (node.message != null) {
      writeWord('"${escapeString(node.message!)}"');
    }
    if (node.expression != null) {
      writeSpaced('in');
      writeNode(node.expression!);
    }
  }

  void _writeDynamicAccessKind(DynamicAccessKind kind) {
    switch (kind) {
      case DynamicAccessKind.Dynamic:
        writeSymbol('{dynamic}.');
        break;
      case DynamicAccessKind.Never:
        writeSymbol('{Never}.');
        break;
      case DynamicAccessKind.Invalid:
        writeSymbol('{<invalid>}.');
        break;
      case DynamicAccessKind.Unresolved:
        writeSymbol('{<unresolved>}.');
        break;
    }
  }

  @override
  void visitDynamicInvocation(DynamicInvocation node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    _writeDynamicAccessKind(node.kind);
    writeName(
      node.name,
    );
    writeNode(node.arguments);
  }

  void _writeFunctionAccessKind(FunctionAccessKind kind) {
    switch (kind) {
      case FunctionAccessKind.Function:
      case FunctionAccessKind.FunctionType:
        break;
      case FunctionAccessKind.Inapplicable:
        writeSymbol('{<inapplicable>}.');
        break;
      case FunctionAccessKind.Nullable:
        writeSymbol('{<nullable>}.');
        break;
    }
  }

  @override
  void visitFunctionInvocation(FunctionInvocation node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    _writeFunctionAccessKind(node.kind);
    writeNode(node.arguments);
    if (node.functionType != null) {
      writeSymbol('{');
      writeType(node.functionType!);
      writeSymbol('}');
    }
  }

  @override
  void visitLocalFunctionInvocation(LocalFunctionInvocation node) {
    writeVariableReference(node.variable);
    writeNode(node.arguments);
    writeSymbol('{');
    writeType(node.functionType);
    writeSymbol('}');
  }

  void _writeInstanceAccessKind(InstanceAccessKind kind) {
    switch (kind) {
      case InstanceAccessKind.Instance:
      case InstanceAccessKind.Object:
        break;
      case InstanceAccessKind.Inapplicable:
        writeSymbol('{<inapplicable>}.');
        break;
      case InstanceAccessKind.Nullable:
        writeSymbol('{<nullable>}.');
        break;
    }
  }

  @override
  void visitInstanceInvocation(InstanceInvocation node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
    _writeInstanceAccessKind(node.kind);
    List<String> flags = <String>[];
    if (node.isInvariant) {
      flags.add('Invariant');
    }
    if (node.isBoundsSafe) {
      flags.add('BoundsSafe');
    }
    if (flags.isNotEmpty) {
      write('{${flags.join(',')}}');
    }
    writeNode(node.arguments);
    writeSymbol('{');
    writeType(node.functionType);
    writeSymbol('}');
  }

  @override
  void visitInstanceGetterInvocation(InstanceGetterInvocation node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
    _writeInstanceAccessKind(node.kind);
    writeNode(node.arguments);
    if (node.functionType != null) {
      writeSymbol('{');
      writeType(node.functionType!);
      writeSymbol('}');
    }
  }

  @override
  void visitEqualsCall(EqualsCall node) {
    int precedence = Precedence.EQUALITY;
    writeExpression(node.left, precedence);
    writeSpace();
    writeSymbol('==');
    writeInterfaceTarget(Name.equalsName, node.interfaceTargetReference);
    writeSymbol('{');
    writeType(node.functionType);
    writeSymbol('}');
    writeSpace();
    writeExpression(node.right, precedence + 1);
  }

  @override
  void visitEqualsNull(EqualsNull node) {
    writeExpression(node.expression, Precedence.EQUALITY);
    writeSpace();
    writeSymbol('==');
    writeSpace();
    writeSymbol('null');
  }

  @override
  void visitSuperMethodInvocation(SuperMethodInvocation node) {
    writeWord('super');
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
    writeNode(node.arguments);
  }

  @override
  void visitStaticInvocation(StaticInvocation node) {
    writeModifier(node.isConst, 'const');
    writeMemberReferenceFromReference(node.targetReference);
    writeNode(node.arguments);
  }

  @override
  void visitConstructorInvocation(ConstructorInvocation node) {
    writeWord(node.isConst ? 'const' : 'new');
    writeMemberReferenceFromReference(node.targetReference);
    writeNode(node.arguments);
  }

  @override
  void visitNot(Not node) {
    writeSymbol('!');
    writeExpression(node.operand, Precedence.PREFIX);
  }

  @override
  void visitNullCheck(NullCheck node) {
    writeExpression(node.operand, Precedence.POSTFIX);
    writeSymbol('!');
  }

  @override
  void visitLogicalExpression(LogicalExpression node) {
    int precedence = Precedence.binaryPrecedence[
        logicalExpressionOperatorToString(node.operatorEnum)]!;
    writeExpression(node.left, precedence);
    writeSpaced(logicalExpressionOperatorToString(node.operatorEnum));
    writeExpression(node.right, precedence + 1);
  }

  @override
  void visitConditionalExpression(ConditionalExpression node) {
    writeExpression(node.condition, Precedence.LOGICAL_OR);
    ensureSpace();
    write('?');
    writeStaticType(node.staticType);
    writeSpace();
    writeExpression(node.then);
    writeSpaced(':');
    writeExpression(node.otherwise);
  }

  @override
  void visitStringConcatenation(StringConcatenation node) {
    if (state == WORD) {
      writeSpace();
    }
    write('"');
    for (Expression part in node.expressions) {
      if (part is StringLiteral) {
        writeSymbol(escapeString(part.value));
      } else {
        writeSymbol(r'${');
        writeExpression(part);
        writeSymbol('}');
      }
    }
    write('"');
    state = WORD;
  }

  @override
  void visitListConcatenation(ListConcatenation node) {
    bool first = true;
    for (Expression part in node.lists) {
      if (!first) writeSpaced('+');
      writeExpression(part);
      first = false;
    }
  }

  @override
  void visitSetConcatenation(SetConcatenation node) {
    bool first = true;
    for (Expression part in node.sets) {
      if (!first) writeSpaced('+');
      writeExpression(part);
      first = false;
    }
  }

  @override
  void visitMapConcatenation(MapConcatenation node) {
    bool first = true;
    for (Expression part in node.maps) {
      if (!first) writeSpaced('+');
      writeExpression(part);
      first = false;
    }
  }

  @override
  void visitInstanceCreation(InstanceCreation node) {
    writeClassReferenceFromReference(node.classReference);
    if (node.typeArguments.isNotEmpty) {
      writeSymbol('<');
      writeList(node.typeArguments, writeType);
      writeSymbol('>');
    }
    writeSymbol('{');
    bool first = true;
    node.fieldValues.forEach((Reference fieldRef, Expression value) {
      if (!first) {
        writeComma();
      }
      writeWord('${fieldRef.asField.name.text}');
      writeSymbol(':');
      writeExpression(value);
      first = false;
    });
    for (AssertStatement assert_ in node.asserts) {
      if (!first) {
        writeComma();
      }
      write('assert(');
      writeExpression(assert_.condition);
      Expression? message = assert_.message;
      if (message != null) {
        writeComma();
        writeExpression(message);
      }
      write(')');
      first = false;
    }
    for (Expression unusedArgument in node.unusedArguments) {
      if (!first) {
        writeComma();
      }
      writeExpression(unusedArgument);
      first = false;
    }
    writeSymbol('}');
  }

  @override
  void visitFileUriExpression(FileUriExpression node) {
    writeExpression(node.expression);
  }

  @override
  void visitIsExpression(IsExpression node) {
    writeExpression(node.operand, Precedence.BITWISE_OR);
    writeSpaced(
        node.isForNonNullableByDefault ? 'is{ForNonNullableByDefault}' : 'is');
    writeType(node.type);
  }

  @override
  void visitAsExpression(AsExpression node) {
    writeExpression(node.operand, Precedence.BITWISE_OR);
    List<String> flags = <String>[];
    if (node.isTypeError) {
      flags.add('TypeError');
    }
    if (node.isCovarianceCheck) {
      flags.add('CovarianceCheck');
    }
    if (node.isForDynamic) {
      flags.add('ForDynamic');
    }
    if (node.isForNonNullableByDefault) {
      flags.add('ForNonNullableByDefault');
    }
    writeSpaced(flags.isNotEmpty ? 'as{${flags.join(',')}}' : 'as');
    writeType(node.type);
  }

  @override
  void visitSymbolLiteral(SymbolLiteral node) {
    writeSymbol('#');
    writeWord(node.value);
  }

  @override
  void visitTypeLiteral(TypeLiteral node) {
    writeType(node.type);
  }

  @override
  void visitThisExpression(ThisExpression node) {
    writeWord('this');
  }

  @override
  void visitRethrow(Rethrow node) {
    writeWord('rethrow');
  }

  @override
  void visitThrow(Throw node) {
    writeWord('throw');
    writeSpace();
    writeExpression(node.expression);
  }

  @override
  void visitListLiteral(ListLiteral node) {
    if (node.isConst) {
      writeWord('const');
      writeSpace();
    }
    // ignore: unnecessary_null_comparison
    if (node.typeArgument != null) {
      writeSymbol('<');
      writeType(node.typeArgument);
      writeSymbol('>');
    }
    writeSymbol('[');
    writeList(node.expressions, writeNode);
    writeSymbol(']');
  }

  @override
  void visitSetLiteral(SetLiteral node) {
    if (node.isConst) {
      writeWord('const');
      writeSpace();
    }
    // ignore: unnecessary_null_comparison
    if (node.typeArgument != null) {
      writeSymbol('<');
      writeType(node.typeArgument);
      writeSymbol('>');
    }
    writeSymbol('{');
    writeList(node.expressions, writeNode);
    writeSymbol('}');
  }

  @override
  void visitMapLiteral(MapLiteral node) {
    if (node.isConst) {
      writeWord('const');
      writeSpace();
    }
    // ignore: unnecessary_null_comparison
    if (node.keyType != null) {
      writeSymbol('<');
      writeList([node.keyType, node.valueType], writeType);
      writeSymbol('>');
    }
    writeSymbol('{');
    writeList(node.entries, writeNode);
    writeSymbol('}');
  }

  @override
  void visitMapLiteralEntry(MapLiteralEntry node) {
    writeExpression(node.key);
    writeComma(':');
    writeExpression(node.value);
  }

  @override
  void visitAwaitExpression(AwaitExpression node) {
    writeWord('await');
    writeExpression(node.operand);
  }

  @override
  void visitFunctionExpression(FunctionExpression node) {
    writeFunction(node.function, terminateLine: false);
  }

  @override
  void visitStringLiteral(StringLiteral node) {
    writeWord('"${escapeString(node.value)}"');
  }

  @override
  void visitIntLiteral(IntLiteral node) {
    writeWord('${node.value}');
  }

  @override
  void visitDoubleLiteral(DoubleLiteral node) {
    writeWord('${node.value}');
  }

  @override
  void visitBoolLiteral(BoolLiteral node) {
    writeWord('${node.value}');
  }

  @override
  void visitNullLiteral(NullLiteral node) {
    writeWord('null');
  }

  @override
  void visitLet(Let node) {
    writeWord('let');
    writeVariableDeclaration(node.variable);
    writeSpaced('in');
    writeExpression(node.body);
  }

  @override
  void visitBlockExpression(BlockExpression node) {
    writeSpaced('block');
    writeBlockBody(node.body.statements, asExpression: true);
    writeSymbol(' =>');
    writeExpression(node.value);
  }

  @override
  void visitInstantiation(Instantiation node) {
    writeExpression(node.expression, Precedence.TYPE_LITERAL);
    writeSymbol('<');
    writeList(node.typeArguments, writeType);
    writeSymbol('>');
  }

  @override
  void visitLoadLibrary(LoadLibrary node) {
    writeWord('LoadLibrary');
    writeSymbol('(');
    writeWord(node.import.name!);
    writeSymbol(')');
    state = WORD;
  }

  @override
  void visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
    writeWord('CheckLibraryIsLoaded');
    writeSymbol('(');
    writeWord(node.import.name!);
    writeSymbol(')');
    state = WORD;
  }

  @override
  void visitLibraryPart(LibraryPart node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeWord('part');
    writeWord(node.partUri);
    endLine(";");
  }

  @override
  void visitLibraryDependency(LibraryDependency node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeWord(node.isImport ? 'import' : 'export');
    String uriString;
    if (node.importedLibraryReference.node != null) {
      uriString = '${node.targetLibrary.importUri}';
    } else {
      uriString = '${node.importedLibraryReference.canonicalName?.name}';
    }
    writeWord('"$uriString"');
    if (node.isDeferred) {
      writeWord('deferred');
    }
    String? name = node.name;
    if (name != null) {
      writeWord('as');
      writeWord(name);
    }
    String? last;
    final String show = 'show';
    final String hide = 'hide';
    if (node.combinators.isNotEmpty) {
      for (Combinator combinator in node.combinators) {
        if (combinator.isShow && last != show) {
          last = show;
          writeWord(show);
        } else if (combinator.isHide && last != hide) {
          last = hide;
          writeWord(hide);
        }

        bool first = true;
        for (String name in combinator.names) {
          if (!first) writeComma();
          writeWord(name);
          first = false;
        }
      }
    }
    endLine(';');
  }

  @override
  void defaultExpression(Expression node) {
    writeWord('${node.runtimeType}');
  }

  @override
  void visitVariableGet(VariableGet node) {
    writeVariableReference(node.variable);
    DartType? promotedType = node.promotedType;
    if (promotedType != null) {
      writeSymbol('{');
      writeNode(promotedType);
      writeSymbol('}');
      state = WORD;
    }
  }

  @override
  void visitVariableSet(VariableSet node) {
    writeVariableReference(node.variable);
    writeSpaced('=');
    writeExpression(node.value);
  }

  void writeInterfaceTarget(Name name, Reference? target) {
    if (target != null) {
      writeSymbol('{');
      writeMemberReferenceFromReference(target);
      writeSymbol('}');
    } else {
      writeName(name);
    }
  }

  void writeStaticType(DartType type) {
    // ignore: unnecessary_null_comparison
    if (type != null) {
      writeSymbol('{');
      writeType(type);
      writeSymbol('}');
    }
  }

  @override
  void visitDynamicGet(DynamicGet node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    _writeDynamicAccessKind(node.kind);
    writeName(node.name);
  }

  @override
  void visitFunctionTearOff(FunctionTearOff node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    writeSymbol('.');
    writeSymbol('call');
  }

  @override
  void visitInstanceGet(InstanceGet node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
    _writeInstanceAccessKind(node.kind);
    writeSymbol('{');
    writeType(node.resultType);
    writeSymbol('}');
  }

  @override
  void visitInstanceTearOff(InstanceTearOff node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
    _writeInstanceAccessKind(node.kind);
    writeSymbol('{');
    writeType(node.resultType);
    writeSymbol('}');
  }

  @override
  void visitDynamicSet(DynamicSet node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    _writeDynamicAccessKind(node.kind);
    writeName(node.name);
    writeSpaced('=');
    writeExpression(node.value);
  }

  @override
  void visitInstanceSet(InstanceSet node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
    _writeInstanceAccessKind(node.kind);
    writeSpaced('=');
    writeExpression(node.value);
  }

  @override
  void visitSuperPropertyGet(SuperPropertyGet node) {
    writeWord('super');
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
  }

  @override
  void visitSuperPropertySet(SuperPropertySet node) {
    writeWord('super');
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
    writeSpaced('=');
    writeExpression(node.value);
  }

  @override
  void visitStaticTearOff(StaticTearOff node) {
    writeMemberReferenceFromReference(node.targetReference);
  }

  @override
  void visitStaticGet(StaticGet node) {
    writeMemberReferenceFromReference(node.targetReference);
  }

  @override
  void visitStaticSet(StaticSet node) {
    writeMemberReferenceFromReference(node.targetReference);
    writeSpaced('=');
    writeExpression(node.value);
  }

  @override
  void visitConstructorTearOff(ConstructorTearOff node) {
    writeMemberReferenceFromReference(node.targetReference);
  }

  @override
  void visitRedirectingFactoryTearOff(RedirectingFactoryTearOff node) {
    writeMemberReferenceFromReference(node.targetReference);
  }

  @override
  void visitTypedefTearOff(TypedefTearOff node) {
    writeTypeParameterList(node.typeParameters);
    state = SYMBOL;
    writeSymbol('.(');
    writeNode(node.expression);
    if (node.typeArguments.isNotEmpty) {
      writeSymbol('<');
      writeList(node.typeArguments, writeType);
      writeSymbol('>');
    }
    writeSymbol(')');
    state = WORD;
  }

  @override
  void visitExpressionStatement(ExpressionStatement node) {
    writeIndentation();
    writeExpression(node.expression);
    endLine(';');
  }

  void writeBlockBody(List<Statement> statements, {bool asExpression = false}) {
    if (statements.isEmpty) {
      asExpression ? writeSymbol('{}') : endLine('{}');
      return;
    }
    endLine('{');
    ++indentation;
    statements.forEach(writeNode);
    --indentation;
    writeIndentation();
    asExpression ? writeSymbol('}') : endLine('}');
  }

  @override
  void visitBlock(Block node) {
    writeIndentation();
    writeBlockBody(node.statements);
  }

  @override
  void visitAssertBlock(AssertBlock node) {
    writeIndentation();
    writeSpaced('assert');
    writeBlockBody(node.statements);
  }

  @override
  void visitEmptyStatement(EmptyStatement node) {
    writeIndentation();
    endLine(';');
  }

  @override
  void visitAssertStatement(AssertStatement node, {bool asExpression = false}) {
    if (!asExpression) {
      writeIndentation();
    }
    writeWord('assert');
    writeSymbol('(');
    writeExpression(node.condition);
    Expression? message = node.message;
    if (message != null) {
      writeComma();
      writeExpression(message);
    }
    if (!asExpression) {
      endLine(');');
    } else {
      writeSymbol(')');
    }
  }

  @override
  void visitLabeledStatement(LabeledStatement node) {
    writeIndentation();
    writeWord(syntheticNames.nameLabeledStatement(node));
    endLine(':');
    writeNode(node.body);
  }

  @override
  void visitBreakStatement(BreakStatement node) {
    writeIndentation();
    writeWord('break');
    writeWord(syntheticNames.nameLabeledStatement(node.target));
    endLine(';');
  }

  @override
  void visitWhileStatement(WhileStatement node) {
    writeIndentation();
    writeSpaced('while');
    writeSymbol('(');
    writeExpression(node.condition);
    writeSymbol(')');
    writeBody(node.body);
  }

  @override
  void visitDoStatement(DoStatement node) {
    writeIndentation();
    writeWord('do');
    writeBody(node.body);
    writeIndentation();
    writeSpaced('while');
    writeSymbol('(');
    writeExpression(node.condition);
    endLine(')');
  }

  @override
  void visitForStatement(ForStatement node) {
    writeIndentation();
    writeSpaced('for');
    writeSymbol('(');
    writeList(node.variables, writeVariableDeclaration);
    writeComma(';');
    Expression? condition = node.condition;
    if (condition != null) {
      writeExpression(condition);
    }
    writeComma(';');
    writeList(node.updates, writeExpression);
    writeSymbol(')');
    writeBody(node.body);
  }

  @override
  void visitForInStatement(ForInStatement node) {
    writeIndentation();
    if (node.isAsync) {
      writeSpaced('await');
    }
    writeSpaced('for');
    writeSymbol('(');
    writeVariableDeclaration(node.variable, useVarKeyword: true);
    writeSpaced('in');
    writeExpression(node.iterable);
    writeSymbol(')');
    writeBody(node.body);
  }

  @override
  void visitSwitchStatement(SwitchStatement node) {
    writeIndentation();
    writeWord('switch');
    writeSymbol('(');
    writeExpression(node.expression);
    endLine(') {');
    ++indentation;
    node.cases.forEach(writeNode);
    --indentation;
    writeIndentation();
    endLine('}');
  }

  @override
  void visitSwitchCase(SwitchCase node) {
    String label = syntheticNames.nameSwitchCase(node);
    writeIndentation();
    writeWord(label);
    endLine(':');
    for (Expression expression in node.expressions) {
      writeIndentation();
      writeWord('case');
      writeExpression(expression);
      endLine(':');
    }
    if (node.isDefault) {
      writeIndentation();
      writeWord('default');
      endLine(':');
    }
    ++indentation;
    writeNode(node.body);
    --indentation;
  }

  @override
  void visitContinueSwitchStatement(ContinueSwitchStatement node) {
    writeIndentation();
    writeWord('continue');
    writeWord(syntheticNames.nameSwitchCase(node.target));
    endLine(';');
  }

  @override
  void visitIfStatement(IfStatement node) {
    writeIndentation();
    writeWord('if');
    writeSymbol('(');
    writeExpression(node.condition);
    writeSymbol(')');
    writeBody(node.then);
    Statement? otherwise = node.otherwise;
    if (otherwise != null) {
      writeIndentation();
      writeWord('else');
      writeBody(otherwise);
    }
  }

  @override
  void visitReturnStatement(ReturnStatement node) {
    writeIndentation();
    writeWord('return');
    Expression? expression = node.expression;
    if (expression != null) {
      writeSpace();
      writeExpression(expression);
    }
    endLine(';');
  }

  @override
  void visitTryCatch(TryCatch node) {
    writeIndentation();
    writeWord('try');
    writeBody(node.body);
    node.catches.forEach(writeNode);
  }

  @override
  void visitCatch(Catch node) {
    writeIndentation();
    // ignore: unnecessary_null_comparison
    if (node.guard != null) {
      writeWord('on');
      writeType(node.guard);
      writeSpace();
    }
    writeWord('catch');
    writeSymbol('(');
    VariableDeclaration? exception = node.exception;
    if (exception != null) {
      writeVariableDeclaration(exception);
    } else {
      writeWord('no-exception-var');
    }
    VariableDeclaration? stackTrace = node.stackTrace;
    if (stackTrace != null) {
      writeComma();
      writeVariableDeclaration(stackTrace);
    }
    writeSymbol(')');
    writeBody(node.body);
  }

  @override
  void visitTryFinally(TryFinally node) {
    writeIndentation();
    writeWord('try');
    writeBody(node.body);
    writeIndentation();
    writeWord('finally');
    writeBody(node.finalizer);
  }

  @override
  void visitYieldStatement(YieldStatement node) {
    writeIndentation();
    if (node.isYieldStar) {
      writeWord('yield*');
    } else if (node.isNative) {
      writeWord('[yield]');
    } else {
      writeWord('yield');
    }
    writeExpression(node.expression);
    endLine(';');
  }

  @override
  void visitVariableDeclaration(VariableDeclaration node) {
    writeIndentation();
    writeVariableDeclaration(node, useVarKeyword: true);
    endLine(';');
  }

  @override
  void visitFunctionDeclaration(FunctionDeclaration node) {
    writeAnnotationList(node.variable.annotations);
    writeIndentation();
    writeWord('function');
    // ignore: unnecessary_null_comparison
    if (node.function != null) {
      writeFunction(node.function, name: getVariableName(node.variable));
    } else {
      writeWord(getVariableName(node.variable));
      endLine('...;');
    }
  }

  void writeVariableDeclaration(VariableDeclaration node,
      {bool useVarKeyword: false}) {
    if (showOffsets) writeWord("[${node.fileOffset}]");
    if (showMetadata) writeMetadata(node);
    writeAnnotationList(node.annotations, separateLines: false);
    writeModifier(node.isLowered, 'lowered');
    writeModifier(node.isLate, 'late');
    writeModifier(node.isRequired, 'required');
    writeModifier(node.isCovariantByDeclaration, 'covariant-by-declaration');
    writeModifier(node.isCovariantByClass, 'covariant-by-class');
    writeModifier(node.isFinal, 'final');
    writeModifier(node.isConst, 'const');
    // ignore: unnecessary_null_comparison
    if (node.type != null) {
      writeAnnotatedType(node.type, annotator?.annotateVariable(this, node));
    }
    // ignore: unnecessary_null_comparison
    if (useVarKeyword && !node.isFinal && !node.isConst && node.type == null) {
      writeWord('var');
    }
    writeWord(getVariableName(node));
    Expression? initializer = node.initializer;
    if (initializer != null) {
      writeSpaced('=');
      writeExpression(initializer);
    }
  }

  @override
  void visitArguments(Arguments node) {
    if (node.types.isNotEmpty) {
      writeSymbol('<');
      writeList(node.types, writeType);
      writeSymbol('>');
    }
    writeSymbol('(');
    Iterable<TreeNode> allArgs =
        <List<TreeNode>>[node.positional, node.named].expand((x) => x);
    writeList(allArgs, writeNode);
    writeSymbol(')');
  }

  @override
  void visitNamedExpression(NamedExpression node) {
    writeWord(node.name);
    writeComma(':');
    writeExpression(node.value);
  }

  @override
  void defaultStatement(Statement node) {
    writeIndentation();
    endLine('${node.runtimeType}');
  }

  @override
  void visitInvalidInitializer(InvalidInitializer node) {
    writeWord('invalid-initializer');
  }

  @override
  void visitFieldInitializer(FieldInitializer node) {
    writeMemberReferenceFromReference(node.fieldReference);
    writeSpaced('=');
    writeExpression(node.value);
  }

  @override
  void visitSuperInitializer(SuperInitializer node) {
    writeWord('super');
    writeMemberReferenceFromReference(node.targetReference);
    writeNode(node.arguments);
  }

  @override
  void visitRedirectingInitializer(RedirectingInitializer node) {
    writeWord('this');
    writeMemberReferenceFromReference(node.targetReference);
    writeNode(node.arguments);
  }

  @override
  void visitLocalInitializer(LocalInitializer node) {
    writeVariableDeclaration(node.variable);
  }

  @override
  void visitAssertInitializer(AssertInitializer node) {
    visitAssertStatement(node.statement, asExpression: true);
  }

  @override
  void defaultInitializer(Initializer node) {
    writeIndentation();
    endLine(': ${node.runtimeType}');
  }

  void writeNullability(Nullability nullability, {bool inComment = false}) {
    switch (nullability) {
      case Nullability.legacy:
        writeSymbol('*');
        if (!inComment) {
          state = WORD; // Disallow a word immediately after the '*'.
        }
        break;
      case Nullability.nullable:
        writeSymbol('?');
        if (!inComment) {
          state = WORD; // Disallow a word immediately after the '?'.
        }
        break;
      case Nullability.undetermined:
        writeSymbol('%');
        if (!inComment) {
          state = WORD; // Disallow a word immediately after the '%'.
        }
        break;
      case Nullability.nonNullable:
        if (inComment) {
          writeSymbol("!");
        }
        break;
    }
  }

  void writeDartTypeNullability(DartType type, {bool inComment = false}) {
    if (type is InvalidType) {
      writeNullability(Nullability.undetermined);
    } else {
      writeNullability(type.nullability, inComment: inComment);
    }
  }

  @override
  void visitInvalidType(InvalidType node) {
    writeWord('invalid-type');
  }

  @override
  void visitDynamicType(DynamicType node) {
    writeWord('dynamic');
  }

  @override
  void visitVoidType(VoidType node) {
    writeWord('void');
  }

  @override
  void visitNeverType(NeverType node) {
    writeWord('Never');
    writeNullability(node.nullability);
  }

  @override
  void visitNullType(NullType node) {
    writeWord('Null');
  }

  @override
  void visitInterfaceType(InterfaceType node) {
    writeClassReferenceFromReference(node.className);
    if (node.typeArguments.isNotEmpty) {
      writeSymbol('<');
      writeList(node.typeArguments, writeType);
      writeSymbol('>');
      state = WORD; // Disallow a word immediately after the '>'.
    }
    writeNullability(node.nullability);
  }

  @override
  void visitExtensionType(ExtensionType node) {
    writeExtensionReferenceFromReference(node.extensionReference);
    if (node.typeArguments.isNotEmpty) {
      writeSymbol('<');
      writeList(node.typeArguments, writeType);
      writeSymbol('>');
      state = Printer.WORD;
    }
    writeNullability(node.declaredNullability);
  }

  @override
  void visitFutureOrType(FutureOrType node) {
    writeWord('FutureOr');
    writeSymbol('<');
    writeNode(node.typeArgument);
    writeSymbol('>');
    writeNullability(node.declaredNullability);
  }

  @override
  void visitFunctionType(FunctionType node) {
    writeFunctionType(node);
  }

  @override
  void visitNamedType(NamedType node) {
    writeModifier(node.isRequired, 'required');
    writeWord(node.name);
    writeSymbol(':');
    writeSpace();
    writeType(node.type);
  }

  @override
  void visitTypeParameterType(TypeParameterType node) {
    writeTypeParameterReference(node.parameter);
    writeNullability(node.declaredNullability);
    DartType? promotedBound = node.promotedBound;
    if (promotedBound != null) {
      writeSpaced('&');
      writeType(promotedBound);

      writeWord("/* '");
      writeNullability(node.declaredNullability, inComment: true);
      writeWord("' & '");
      writeDartTypeNullability(promotedBound, inComment: true);
      writeWord("' = '");
      writeNullability(node.nullability, inComment: true);
      writeWord("' */");
    }
  }

  @override
  void visitTypeParameter(TypeParameter node) {
    writeModifier(node.isCovariantByClass, 'covariant-by-class');
    writeAnnotationList(node.annotations, separateLines: false);
    if (node.variance != Variance.covariant) {
      writeWord(const <String>[
        "unrelated",
        "covariant",
        "contravariant",
        "invariant"
      ][node.variance]);
    }
    writeWord(getTypeParameterName(node));
    writeSpaced('extends');
    writeType(node.bound);
    // ignore: unnecessary_null_comparison
    if (node.defaultType != node.bound) {
      writeSpaced('=');
      writeType(node.defaultType);
    }
  }

  void writeConstantReference(Constant node) {
    writeWord(syntheticNames.nameConstant(node));
  }

  @override
  void visitConstantExpression(ConstantExpression node) {
    writeConstantReference(node.constant);
  }

  @override
  void defaultConstant(Constant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    endLine('${node.runtimeType}');
  }

  @override
  void visitNullConstant(NullConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    endLine('${node.value}');
  }

  @override
  void visitBoolConstant(BoolConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    endLine('${node.value}');
  }

  @override
  void visitIntConstant(IntConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    endLine('${node.value}');
  }

  @override
  void visitDoubleConstant(DoubleConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    endLine('${node.value}');
  }

  @override
  void visitSymbolConstant(SymbolConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    Reference? libraryReference = node.libraryReference;
    String text = libraryReference != null
        ? '#${libraryReference.asLibrary.importUri}::${node.name}'
        : '#${node.name}';
    endLine('${text}');
  }

  @override
  void visitListConstant(ListConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeSymbol('<');
    writeType(node.typeArgument);
    writeSymbol('>[');
    writeList(node.entries, writeConstantReference);
    endLine(']');
  }

  @override
  void visitSetConstant(SetConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeSymbol('<');
    writeType(node.typeArgument);
    writeSymbol('>{');
    writeList(node.entries, writeConstantReference);
    endLine('}');
  }

  @override
  void visitMapConstant(MapConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeSymbol('<');
    writeList([node.keyType, node.valueType], writeType);
    writeSymbol('>{');
    writeList(node.entries, (ConstantMapEntry entry) {
      writeConstantReference(entry.key);
      writeSymbol(':');
      writeConstantReference(entry.value);
    });
    endLine(')');
  }

  @override
  void visitTypeLiteralConstant(TypeLiteralConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeWord('${node.runtimeType}');
    writeSymbol('(');
    writeNode(node.type);
    endLine(')');
  }

  @override
  void visitInstanceConstant(InstanceConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeClassReferenceFromReference(node.classReference);
    if (!node.typeArguments.isEmpty) {
      writeSymbol('<');
      writeList(node.typeArguments, writeType);
      writeSymbol('>');
    }

    writeSymbol(' {');
    writeList(node.fieldValues.entries, (MapEntry<Reference, Constant> entry) {
      if (entry.key.node != null) {
        writeWord('${entry.key.asField.name.text}');
      } else {
        writeWord('${entry.key.canonicalName!.name}');
      }
      writeSymbol(':');
      writeConstantReference(entry.value);
    });
    endLine('}');
  }

  @override
  void visitInstantiationConstant(InstantiationConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeWord('instantiation');
    writeSpace();
    writeConstantReference(node.tearOffConstant);
    writeSpace();
    writeSymbol('<');
    writeList(node.types, writeType);
    writeSymbol('>');
    endLine();
  }

  @override
  void visitStringConstant(StringConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    endLine('"${escapeString(node.value)}"');
  }

  @override
  void visitStaticTearOffConstant(StaticTearOffConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeWord('static-tearoff');
    writeSpace();
    writeMemberReferenceFromReference(node.targetReference);
    endLine();
  }

  @override
  void visitTypedefTearOffConstant(TypedefTearOffConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeWord('typedef-tearoff');
    writeSpace();
    writeTypeParameterList(node.parameters);
    state = SYMBOL;
    writeSymbol('.(');
    writeConstantReference(node.tearOffConstant);
    if (node.types.isNotEmpty) {
      writeSymbol('<');
      writeList(node.types, writeType);
      writeSymbol('>');
    }
    writeSymbol(')');
    state = WORD;
    endLine();
  }

  @override
  void visitUnevaluatedConstant(UnevaluatedConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeSymbol('eval');
    writeSpace();
    writeExpression(node.expression);
    endLine();
  }

  @override
  void visitConstructorTearOffConstant(ConstructorTearOffConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeWord('constructor-tearoff');
    writeSpace();
    writeMemberReferenceFromReference(node.targetReference);
    endLine();
  }

  @override
  void visitRedirectingFactoryTearOffConstant(
      RedirectingFactoryTearOffConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeWord('redirecting-factory-tearoff');
    writeSpace();
    writeMemberReferenceFromReference(node.targetReference);
    endLine();
  }

  @override
  void defaultNode(Node node) {
    write('<${node.runtimeType}>');
  }
}

class Precedence implements ExpressionVisitor<int> {
  static final Precedence instance = new Precedence();

  static int of(Expression node) => node.accept(instance);

  static const int EXPRESSION = 1;
  static const int CONDITIONAL = 2;
  static const int LOGICAL_NULL_AWARE = 3;
  static const int LOGICAL_OR = 4;
  static const int LOGICAL_AND = 5;
  static const int EQUALITY = 6;
  static const int RELATIONAL = 7;
  static const int BITWISE_OR = 8;
  static const int BITWISE_XOR = 9;
  static const int BITWISE_AND = 10;
  static const int SHIFT = 11;
  static const int ADDITIVE = 12;
  static const int MULTIPLICATIVE = 13;
  static const int PREFIX = 14;
  static const int POSTFIX = 15;
  static const int TYPE_LITERAL = 19;
  static const int PRIMARY = 20;
  static const int CALLEE = 21;

  static const Map<String?, int> binaryPrecedence = const {
    '&&': LOGICAL_AND,
    '||': LOGICAL_OR,
    '??': LOGICAL_NULL_AWARE,
    '==': EQUALITY,
    '!=': EQUALITY,
    '>': RELATIONAL,
    '>=': RELATIONAL,
    '<': RELATIONAL,
    '<=': RELATIONAL,
    '|': BITWISE_OR,
    '^': BITWISE_XOR,
    '&': BITWISE_AND,
    '>>': SHIFT,
    '<<': SHIFT,
    '+': ADDITIVE,
    '-': ADDITIVE,
    '*': MULTIPLICATIVE,
    '%': MULTIPLICATIVE,
    '/': MULTIPLICATIVE,
    '~/': MULTIPLICATIVE,
    null: EXPRESSION,
  };

  static bool isAssociativeBinaryOperator(int precedence) {
    return precedence != EQUALITY && precedence != RELATIONAL;
  }

  @override
  int defaultExpression(Expression node) => EXPRESSION;

  @override
  int visitInvalidExpression(InvalidExpression node) => CALLEE;

  @override
  int visitInstanceInvocation(InstanceInvocation node) => CALLEE;

  @override
  int visitInstanceGetterInvocation(InstanceGetterInvocation node) => CALLEE;

  @override
  int visitDynamicInvocation(DynamicInvocation node) => CALLEE;

  @override
  int visitFunctionInvocation(FunctionInvocation node) => CALLEE;

  @override
  int visitLocalFunctionInvocation(LocalFunctionInvocation node) => CALLEE;

  @override
  int visitEqualsCall(EqualsCall node) => EQUALITY;

  @override
  int visitEqualsNull(EqualsNull node) => EQUALITY;

  @override
  int visitSuperMethodInvocation(SuperMethodInvocation node) => CALLEE;

  @override
  int visitStaticInvocation(StaticInvocation node) => CALLEE;

  @override
  int visitConstructorInvocation(ConstructorInvocation node) => CALLEE;

  @override
  int visitNot(Not node) => PREFIX;

  @override
  int visitNullCheck(NullCheck node) => PRIMARY;

  @override
  int visitLogicalExpression(LogicalExpression node) =>
      binaryPrecedence[logicalExpressionOperatorToString(node.operatorEnum)]!;

  @override
  int visitConditionalExpression(ConditionalExpression node) => CONDITIONAL;

  @override
  int visitStringConcatenation(StringConcatenation node) => PRIMARY;

  @override
  int visitIsExpression(IsExpression node) => RELATIONAL;

  @override
  int visitAsExpression(AsExpression node) => RELATIONAL;

  @override
  int visitSymbolLiteral(SymbolLiteral node) => PRIMARY;

  @override
  int visitTypeLiteral(TypeLiteral node) => PRIMARY;

  @override
  int visitThisExpression(ThisExpression node) => CALLEE;

  @override
  int visitRethrow(Rethrow node) => PRIMARY;

  @override
  int visitThrow(Throw node) => EXPRESSION;

  @override
  int visitListLiteral(ListLiteral node) => PRIMARY;

  @override
  int visitSetLiteral(SetLiteral node) => PRIMARY;

  @override
  int visitMapLiteral(MapLiteral node) => PRIMARY;

  @override
  int visitAwaitExpression(AwaitExpression node) => PREFIX;

  @override
  int visitFunctionExpression(FunctionExpression node) => EXPRESSION;

  @override
  int visitStringLiteral(StringLiteral node) => CALLEE;

  @override
  int visitIntLiteral(IntLiteral node) => CALLEE;

  @override
  int visitDoubleLiteral(DoubleLiteral node) => CALLEE;

  @override
  int visitBoolLiteral(BoolLiteral node) => CALLEE;

  @override
  int visitNullLiteral(NullLiteral node) => CALLEE;

  @override
  int visitVariableGet(VariableGet node) => PRIMARY;

  @override
  int visitVariableSet(VariableSet node) => EXPRESSION;

  @override
  int visitInstanceGet(InstanceGet node) => PRIMARY;

  @override
  int visitDynamicGet(DynamicGet node) => PRIMARY;

  @override
  int visitInstanceTearOff(InstanceTearOff node) => PRIMARY;

  @override
  int visitFunctionTearOff(FunctionTearOff node) => PRIMARY;

  @override
  int visitSuperPropertyGet(SuperPropertyGet node) => PRIMARY;

  @override
  int visitSuperPropertySet(SuperPropertySet node) => EXPRESSION;

  @override
  int visitStaticGet(StaticGet node) => PRIMARY;

  @override
  int visitStaticTearOff(StaticTearOff node) => PRIMARY;

  @override
  int visitStaticSet(StaticSet node) => EXPRESSION;

  @override
  int visitConstructorTearOff(ConstructorTearOff node) => PRIMARY;

  @override
  int visitRedirectingFactoryTearOff(RedirectingFactoryTearOff node) => PRIMARY;

  @override
  int visitTypedefTearOff(TypedefTearOff node) => EXPRESSION;

  @override
  int visitLet(Let node) => EXPRESSION;

  @override
  int defaultBasicLiteral(BasicLiteral node) => CALLEE;

  @override
  int visitBlockExpression(BlockExpression node) => EXPRESSION;

  @override
  int visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) => EXPRESSION;

  @override
  int visitConstantExpression(ConstantExpression node) => PRIMARY;

  @override
  int visitDynamicSet(DynamicSet node) => EXPRESSION;

  @override
  int visitFileUriExpression(FileUriExpression node) => EXPRESSION;

  @override
  int visitInstanceCreation(InstanceCreation node) => EXPRESSION;

  @override
  int visitInstanceSet(InstanceSet node) => EXPRESSION;

  @override
  int visitInstantiation(Instantiation node) => EXPRESSION;

  @override
  int visitListConcatenation(ListConcatenation node) => EXPRESSION;

  @override
  int visitLoadLibrary(LoadLibrary node) => EXPRESSION;

  @override
  int visitMapConcatenation(MapConcatenation node) => EXPRESSION;

  @override
  int visitSetConcatenation(SetConcatenation node) => EXPRESSION;
}

String procedureKindToString(ProcedureKind kind) {
  switch (kind) {
    case ProcedureKind.Method:
      return 'method';
    case ProcedureKind.Getter:
      return 'get';
    case ProcedureKind.Setter:
      return 'set';
    case ProcedureKind.Operator:
      return 'operator';
    case ProcedureKind.Factory:
      return 'factory';
  }
}
