// 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' hide MapEntry;
import 'dart:core' as core show MapEntry;

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> {
  final String prefix;

  NormalNamer(this.prefix);
}

class ConstantNamer extends RecursiveResultVisitor<Null> with Namer<Constant> {
  final String prefix;

  ConstantNamer(this.prefix);

  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 TearOffConstant) {
        // 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);
  }

  defaultConstantReference(Constant constant) {
    getName(constant);
  }

  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 ?? globalDebuggingNames.nameClass(node);
}

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

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

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>();

  nameVariable(VariableDeclaration node) => variables.getName(node);
  nameMember(Member node) => members.getName(node);
  nameClass(Class node) => classes.getName(node);
  nameExtension(Extension node) => extensions.getName(node);
  nameLibrary(Library node) => libraries.getName(node);
  nameTypeParameter(TypeParameter node) => typeParameters.getName(node);
  nameSwitchCase(SwitchCase node) => labels.getName(node);
  nameLabeledStatement(LabeledStatement node) => labels.getName(node);
  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';
    });
  }

  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 ?? syntheticNames.nameClass(node);
  }

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

  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 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;
    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, Object> decoded = json.decode(s);
        List<Object> plainTextFormatted =
            decoded["plainTextFormatted"] as List<Object>;
        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);
    }
    if (library.isNonNullableByDefault) {
      writeWord("/*isNonNullableByDefault*/");
    }
    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);
    }
  }

  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('>');
      }
    }
  }

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

  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 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();
      }
    }
  }

  visitLibrary(Library node) {}

  visitField(Field node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeModifier(node.isLate, 'late');
    writeModifier(node.isStatic, 'static');
    writeModifier(node.isCovariant, 'covariant');
    writeModifier(node.isGenericCovariantImpl, 'generic-covariant-impl');
    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(';');
  }

  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(',')}*/");
    }
    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;
    }
  }

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

  visitRedirectingFactoryConstructor(RedirectingFactoryConstructor node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeModifier(node.isExternal, 'external');
    writeModifier(node.isConst, 'const');
    writeWord('redirecting_factory');

    if (node.name != null) {
      writeName(node.name!);
    }
    writeTypeParameterList(node.typeParameters);
    writeParameterList(node.positionalParameters, node.namedParameters,
        node.requiredParameterCount);
    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(';');
  }

  visitClass(Class node) {
    writeAnnotationList(node.annotations);
    writeIndentation();
    writeModifier(node.isAbstract, 'abstract');
    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.redirectingFactoryConstructors.forEach(writeNode);
    --indentation;
    writeIndentation();
    endLine('}');
  }

  visitExtension(Extension node) {
    writeIndentation();
    writeWord('extension');
    writeWord(getExtensionName(node));
    writeTypeParameterList(node.typeParameters);
    writeSpaced('on');
    writeType(node.onType!);
    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('}');
  }

  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(';');
  }

  visitInvalidExpression(InvalidExpression node) {
    writeWord('invalid-expression');
    // ignore: unnecessary_null_comparison
    if (node.message != null) {
      writeWord('"${escapeString(node.message)}"');
    }
  }

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

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

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

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

  visitInstanceInvocation(InstanceInvocation node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
    _writeInstanceAccessKind(node.kind);
    writeNode(node.arguments);
    writeSymbol('{');
    writeType(node.functionType);
    writeSymbol('}');
  }

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

  visitEqualsNull(EqualsNull node) {
    writeExpression(node.expression, Precedence.EQUALITY);
    writeSpace();
    if (node.isNot) {
      writeSymbol('!=');
    } else {
      writeSymbol('==');
    }
    writeSpace();
    writeSymbol('null');
  }

  visitMethodInvocation(MethodInvocation node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
    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);
  }

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

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

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

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

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

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

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

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

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

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

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

  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('}');
  }

  visitFileUriExpression(FileUriExpression node) {
    writeExpression(node.expression);
  }

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

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

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

  visitTypeLiteral(TypeLiteral node) {
    writeType(node.type);
  }

  visitThisExpression(ThisExpression node) {
    writeWord('this');
  }

  visitRethrow(Rethrow node) {
    writeWord('rethrow');
  }

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

  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(']');
  }

  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('}');
  }

  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('}');
  }

  visitMapEntry(MapEntry node) {
    writeExpression(node.key);
    writeComma(':');
    writeExpression(node.value);
  }

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

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

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

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

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

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

  visitNullLiteral(NullLiteral node) {
    writeWord('null');
  }

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

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

  visitInstantiation(Instantiation node) {
    writeExpression(node.expression);
    writeSymbol('<');
    writeList(node.typeArguments, writeType);
    writeSymbol('>');
  }

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

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

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

  visitLibraryDependency(LibraryDependency node) {
    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(';');
  }

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

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

  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('}');
    }
  }

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

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

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

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

  visitPropertyGet(PropertyGet node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
  }

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

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

  visitPropertySet(PropertySet node) {
    writeExpression(node.receiver, Precedence.PRIMARY);
    writeSymbol('.');
    writeInterfaceTarget(node.name, node.interfaceTargetReference);
    writeSpaced('=');
    writeExpression(node.value);
  }

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

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

  visitStaticTearOff(StaticTearOff node) {
    writeMemberReferenceFromReference(node.targetReference);
  }

  visitStaticGet(StaticGet node) {
    writeMemberReferenceFromReference(node.targetReference);
  }

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

  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('}');
  }

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

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

  visitEmptyStatement(EmptyStatement node) {
    writeIndentation();
    endLine(';');
  }

  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(')');
    }
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  visitFunctionDeclaration(FunctionDeclaration node) {
    writeAnnotationList(node.variable.annotations);
    writeIndentation();
    writeWord('function');
    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.isCovariant, 'covariant');
    writeModifier(node.isGenericCovariantImpl, 'generic-covariant-impl');
    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);
    }
  }

  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(')');
  }

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

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

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

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

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

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

  visitLocalInitializer(LocalInitializer node) {
    writeVariableDeclaration(node.variable);
  }

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

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

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

  visitDynamicType(DynamicType node) {
    writeWord('dynamic');
  }

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

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

  visitNullType(NullType node) {
    writeWord('Null');
  }

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

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

  visitFunctionType(FunctionType node) {
    writeFunctionType(node);
  }

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

  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("' */");
    }
  }

  visitTypeParameter(TypeParameter node) {
    writeModifier(node.isGenericCovariantImpl, 'generic-covariant-impl');
    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!);
    if (node.defaultType != null) {
      writeSpaced('=');
      writeType(node.defaultType!);
    }
  }

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

  visitConstantExpression(ConstantExpression node) {
    writeConstantReference(node.constant);
  }

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

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

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

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

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

  visitSymbolConstant(SymbolConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    // ignore: unnecessary_null_comparison
    String text = node.libraryReference != null
        ? '#${node.libraryReference.asLibrary.importUri}::${node.name}'
        : '#${node.name}';
    endLine('${text}');
  }

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

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

  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(')');
  }

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

  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,
        (core.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('}');
  }

  visitPartialInstantiationConstant(PartialInstantiationConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeWord('partial-instantiation');
    writeSpace();
    writeMemberReferenceFromReference(node.tearOffConstant.procedureReference);
    writeSpace();
    writeSymbol('<');
    writeList(node.types, writeType);
    writeSymbol('>');
    endLine();
  }

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

  visitTearOffConstant(TearOffConstant node) {
    writeIndentation();
    writeConstantReference(node);
    writeSpaced('=');
    writeWord('tearoff');
    writeSpace();
    writeMemberReferenceFromReference(node.procedureReference);
    endLine();
  }

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

  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 visitMethodInvocation(MethodInvocation node) => CALLEE;

  @override
  int visitInstanceInvocation(InstanceInvocation 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 visitPropertyGet(PropertyGet node) => PRIMARY;

  @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 visitPropertySet(PropertySet node) => EXPRESSION;

  @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 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) => EXPRESSION;

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