// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import '../ast.dart';
import 'coverage.dart';

/// Helper class used to generate ASTs that contain all different nodes.
class NodeCreator {
  final Uri _uri;

  /// File offset counter.
  ///
  /// Used to generate distinct file offsets through [_needFileOffset].
  int _fileOffset = 0;

  /// The parent [Component] for all created libraries, classes, extensions,
  /// typedefs and members.
  final Component _component = new Component();

  /// These fields contain maps of requested nodes different kinds that are
  /// still pending. The mapped values are used to track how many nodes of the
  /// specific kind have been created. When all variants of a kind have been
  /// created, the entry is removed from the map.
  final Map<ExpressionKind, int> _pendingExpressions;
  final Map<StatementKind, int> _pendingStatements;
  final Map<DartTypeKind, int> _pendingDartTypes;
  final Map<ConstantKind, int> _pendingConstants;
  final Map<PatternKind, int> _pendingPatterns;
  final Map<InitializerKind, int> _pendingInitializers;
  final Map<MemberKind, int> _pendingMembers;
  final Map<NodeKind, int> _pendingNodes;

  /// The set of all kinds of nodes created by this node creator.
  final Set<Object> _createdKinds = {};

  /// These fields contain list of nodes needed for the creation of other nodes.
  ///
  /// Needed nodes are nodes that need to exist prior to the node that required
  /// it. For instance, to create an [InterfaceType] node, a [Class] node must
  /// exist for the [InterfaceType] to reference.
  ///
  /// Needed nodes are added to the context of the created nodes. For instance,
  /// a needed [Class] is added to the [_component] and a needed
  /// [VariableDeclaration] is added to a enclosing [Block].
  List<Library> _neededLibraries = [];
  List<Class> _neededClasses = [];
  List<ExtensionTypeDeclaration> _neededExtensionTypeDeclarations = [];
  List<Typedef> _neededTypedefs = [];
  List<TypeParameter> _neededTypeParameters = [];
  List<StructuralParameter> _neededStructuralParameters = [];
  List<Constructor> _neededConstructors = [];
  List<Procedure> _neededRedirectingFactories = [];
  List<Procedure> _neededProcedures = [];
  List<Field> _neededFields = [];
  List<LibraryDependency> _neededLibraryDependencies = [];
  List<VariableDeclaration> _neededVariableDeclarations = [];
  List<LabeledStatement> _neededLabeledStatements = [];
  List<FunctionDeclaration> _neededFunctionDeclarations = [];
  List<SwitchCase> _neededSwitchCases = [];

  /// Creates a [NodeCreator] requested to create nodes of the specified kinds.
  NodeCreator({
    Iterable<ExpressionKind> expressions = ExpressionKind.values,
    Iterable<StatementKind> statements = StatementKind.values,
    Iterable<DartTypeKind> dartTypes = DartTypeKind.values,
    Iterable<ConstantKind> constants = ConstantKind.values,
    Iterable<PatternKind> patterns = PatternKind.values,
    Iterable<InitializerKind> initializers = InitializerKind.values,
    Iterable<MemberKind> members = MemberKind.values,
    Iterable<NodeKind> nodes = NodeKind.values,
  })  : _pendingExpressions = new Map<ExpressionKind, int>.fromIterables(
            expressions, new List<int>.filled(expressions.length, 0)),
        _pendingStatements = new Map<StatementKind, int>.fromIterables(
            statements, new List<int>.filled(statements.length, 0)),
        _pendingDartTypes = new Map<DartTypeKind, int>.fromIterables(
            dartTypes, new List<int>.filled(dartTypes.length, 0)),
        _pendingConstants = new Map<ConstantKind, int>.fromIterables(
            constants, new List<int>.filled(constants.length, 0)),
        _pendingPatterns = new Map<PatternKind, int>.fromIterables(
            patterns, new List<int>.filled(patterns.length, 0)),
        _pendingInitializers = new Map<InitializerKind, int>.fromIterables(
            initializers, new List<int>.filled(initializers.length, 0)),
        _pendingMembers = new Map<MemberKind, int>.fromIterables(
            members, new List<int>.filled(members.length, 0)),
        _pendingNodes = new Map<NodeKind, int>.fromIterables(
            nodes, new List<int>.filled(nodes.length, 0)),
        _uri = Uri.parse('test:uri') {
    _createdKinds.addAll(_pendingExpressions.keys);
    _createdKinds.addAll(_pendingStatements.keys);
    _createdKinds.addAll(_pendingDartTypes.keys);
    _createdKinds.addAll(_pendingInitializers.keys);
    _createdKinds.addAll(_pendingMembers.keys);
    _createdKinds.addAll(_pendingNodes.keys);
  }

  /// The kinds created by this node creator.
  Iterable<Object> get createdKinds => _createdKinds;

  /// Wraps [statement] in nodes needed in the statement context.
  ///
  /// For instance, if a [LabeledStatement] was needed for the creation of
  /// [statement], [statement] is wrapped inside the labeled statement.
  Statement _ensureContext(Statement statement) {
    if (_neededSwitchCases.isNotEmpty) {
      statement = SwitchStatement(NullLiteral(), [
        ..._neededSwitchCases,
        SwitchCase([NullLiteral()], [TreeNode.noOffset], Block([statement]))
      ]);
    }
    _neededSwitchCases.clear();
    for (LabeledStatement labeledStatement in _neededLabeledStatements) {
      labeledStatement.body = statement;
      statement = labeledStatement;
    }
    _neededLabeledStatements.clear();
    statement = Block([
      ..._neededVariableDeclarations,
      ..._neededFunctionDeclarations,
      statement
    ]);
    _neededFunctionDeclarations.clear();
    _neededVariableDeclarations.clear();
    return statement;
  }

  /// Adds [statement] to [statements] including any nodes needed in the
  /// context.
  void _addStatement(List<Statement> statements, Statement statement) {
    statements.add(_ensureContext(statement));
  }

  /// Adds [expression] to [statements] including any nodes needed in the
  /// context.
  void _addExpression(List<Statement> statements, Expression expression) {
    _addStatement(statements, ExpressionStatement(expression));
  }

  /// Adds [type] to [statements] including any nodes needed in the context.
  void _addDartType(List<Statement> statements, DartType type) {
    _addExpression(statements, TypeLiteral(type));
  }

  /// Adds [constant] to [statements] including any nodes needed in the context.
  void _addConstant(List<Statement> statements, Constant constant) {
    _addExpression(statements, ConstantExpression(constant));
  }

  /// Adds [pattern] to [statements] including any nodes needed in the context.
  void _addPattern(List<Statement> statements, Pattern pattern) {
    _addExpression(statements, PatternAssignment(pattern, NullLiteral()));
  }

  /// Generates a list of [Statement] containing all pending in-body nodes.
  List<Statement> _generateBodies() {
    List<Statement> statements = [];
    while (_pendingStatements.isNotEmpty) {
      _addStatement(statements, _createStatement());
    }
    while (_pendingExpressions.isNotEmpty) {
      _addExpression(statements, _createExpression());
    }
    while (_pendingDartTypes.isNotEmpty) {
      _addDartType(statements, _createDartType());
    }
    while (_pendingConstants.isNotEmpty) {
      _addConstant(statements, _createConstant());
    }
    for (NodeKind kind in inBodyNodeKinds) {
      while (_pendingNodes.containsKey(kind)) {
        Node node = _createNodeFromKind(kind);
        switch (kind) {
          case NodeKind.Name:
            _addExpression(
                statements,
                DynamicGet(DynamicAccessKind.Dynamic, _createExpression(),
                    node as Name));
            break;
          case NodeKind.Arguments:
            _addExpression(
                statements,
                DynamicInvocation(DynamicAccessKind.Dynamic,
                    _createExpression(), _createName(), node as Arguments));
            break;
          case NodeKind.Catch:
            _addStatement(
                statements, TryCatch(_createStatement(), [node as Catch]));
            break;
          case NodeKind.FunctionNode:
            _addExpression(
                statements, FunctionExpression(node as FunctionNode));
            break;
          case NodeKind.MapLiteralEntry:
            _addExpression(statements, MapLiteral([node as MapLiteralEntry]));
            break;
          case NodeKind.MapPatternEntry:
            _addPattern(
                statements, MapPattern(null, null, [node as MapPatternEntry]));
            break;
          case NodeKind.MapPatternRestEntry:
            _addPattern(statements,
                MapPattern(null, null, [node as MapPatternRestEntry]));
            break;
          case NodeKind.NamedExpression:
            _addExpression(
                statements,
                DynamicInvocation(
                    DynamicAccessKind.Dynamic,
                    _createExpression(),
                    _createName(),
                    Arguments([], named: [node as NamedExpression])));
            break;
          case NodeKind.NamedType:
            _addDartType(
                statements,
                FunctionType([], _createDartType(), Nullability.nonNullable,
                    namedParameters: [node as NamedType]));
            break;
          case NodeKind.PatternSwitchCase:
            _addStatement(
                statements,
                PatternSwitchStatement(
                    _createExpression(), [node as PatternSwitchCase]));
            break;
          case NodeKind.SwitchCase:
            _addStatement(statements,
                SwitchStatement(_createExpression(), [node as SwitchCase]));
            break;
          case NodeKind.SwitchExpressionCase:
            _addExpression(
                statements,
                SwitchExpression(
                    _createExpression(), [node as SwitchExpressionCase]));
            break;
          case NodeKind.TypeParameter:
            _addExpression(
                statements,
                FunctionExpression(FunctionNode(Block([]),
                    typeParameters: [node as TypeParameter])));
            break;
          default:
            throw new UnimplementedError('Unhandled in body node $kind.');
        }
      }
    }
    return statements;
  }

  /// Generates [Statement]s containing occurrences of all requested nodes.
  List<Statement> generateBodies() {
    List<Statement> statements = _generateBodies();
    Set<Object> unsupportedKinds = {};
    if (_pendingInitializers.isNotEmpty) {
      unsupportedKinds.addAll(_pendingInitializers.keys);
    }
    if (_pendingMembers.isNotEmpty) {
      unsupportedKinds.addAll(_pendingMembers.keys);
    }
    if (_pendingNodes.isNotEmpty) {
      assert(
          _pendingNodes.keys.every((kind) => !inBodyNodeKinds.contains(kind)));
      unsupportedKinds.addAll(_pendingNodes.keys);
    }
    if (unsupportedKinds.isNotEmpty) {
      throw new UnsupportedError('Cannot create these node in a body context: '
          '${unsupportedKinds.join(', ')}');
    }
    return statements;
  }

  /// Generates a [Component] containing occurrences of all requested and needed
  /// nodes.
  Component generateComponent() {
    Class cls = _needClass();
    for (Statement statement in _generateBodies()) {
      cls.addProcedure(Procedure(
          _createName(), ProcedureKind.Method, FunctionNode(statement),
          fileUri: _uri));
    }
    while (_pendingInitializers.isNotEmpty) {
      Initializer initializer = _createInitializer();
      cls.addConstructor(Constructor(FunctionNode(null),
          name: _createName(), fileUri: _uri, initializers: [initializer]));
    }
    while (_pendingMembers.isNotEmpty) {
      Member member = _createMember();
      if (member is Procedure) {
        cls.addProcedure(member);
      } else if (member is Field) {
        cls.addField(member);
      } else if (member is Constructor) {
        cls.addConstructor(member);
      } else {
        throw new UnsupportedError(
            'Unexpected member $member (${member.runtimeType})');
      }
    }
    while (_pendingNodes.isNotEmpty) {
      NodeKind kind = _pendingNodes.keys.first;
      Node node = _createNodeFromKind(kind);
      switch (kind) {
        case NodeKind.Name:
        case NodeKind.Arguments:
        case NodeKind.Catch:
        case NodeKind.FunctionNode:
        case NodeKind.MapLiteralEntry:
        case NodeKind.NamedExpression:
        case NodeKind.NamedType:
        case NodeKind.SwitchCase:
        case NodeKind.TypeParameter:
        case NodeKind.StructuralParameter:
        case NodeKind.MapPatternEntry:
        case NodeKind.MapPatternRestEntry:
        case NodeKind.PatternGuard:
        case NodeKind.PatternSwitchCase:
        case NodeKind.SwitchExpressionCase:
          throw new UnimplementedError('Expected in body node $kind.');
        case NodeKind.Class:
          _needLibrary().addClass(node as Class);
          break;
        case NodeKind.Combinator:
          _needLibrary().addDependency(LibraryDependency.import(_needLibrary(),
              combinators: [node as Combinator]));
          break;
        case NodeKind.Component:
          assert(identical(node, _component),
              "Cannot create multiple Component nodes.");
          break;
        case NodeKind.Extension:
          _needLibrary().addExtension(node as Extension);
          break;
        case NodeKind.Library:
          _component.libraries.add(node as Library);
          break;
        case NodeKind.LibraryDependency:
          _needLibrary().addDependency(node as LibraryDependency);
          break;
        case NodeKind.LibraryPart:
          _needLibrary().addPart(node as LibraryPart);
          break;
        case NodeKind.Supertype:
          _needLibrary().addClass(
              Class(name: 'foo', fileUri: _uri, supertype: node as Supertype));
          break;
        case NodeKind.Typedef:
          _needLibrary().addTypedef(node as Typedef);
          break;
        case NodeKind.ExtensionTypeDeclaration:
          _needLibrary()
              .addExtensionTypeDeclaration(node as ExtensionTypeDeclaration);
          break;
      }
    }
    return _component;
  }

  /// Returns a [Library] node that fits the requirements.
  ///
  /// If no such [Library] exists in [_neededLibraries], a new [Library] is
  /// created and added to [_neededLibraries].
  // TODO(johnniwinther): Add requirements when/where needed.
  Library _needLibrary() {
    for (Library library in _neededLibraries) {
      return library;
    }
    Library library = Library(_uri, fileUri: _uri);
    _neededLibraries.add(library);
    _component.libraries.add(library);
    return library;
  }

  /// Returns a [LibraryDependency] node that fits the requirements.
  ///
  /// If no such [LibraryDependency] exists in [_neededLibraryDependencies], a
  /// new [LibraryDependency] is created and added to
  /// [_neededLibraryDependencies].
  LibraryDependency _needLibraryDependency({bool deferred = false}) {
    for (LibraryDependency libraryDependency in _neededLibraryDependencies) {
      if (!deferred || libraryDependency.isDeferred) {
        return libraryDependency;
      }
    }
    LibraryDependency libraryDependency = deferred
        ? LibraryDependency.deferredImport(_needLibrary(), 'foo')
        : LibraryDependency.import(_needLibrary());
    _neededLibraryDependencies.add(libraryDependency);
    return libraryDependency;
  }

  /// Returns a [Class] node that fits the requirements.
  ///
  /// If no such [Class] exists in [_neededClasses], a new [Class] is
  /// created and added to [_neededClasses].
  // TODO(johnniwinther): Add requirements when/where needed.
  Class _needClass() {
    for (Class cls in _neededClasses) {
      return cls;
    }
    Class cls = Class(name: 'Foo', fileUri: _uri);
    _neededClasses.add(cls);
    _needLibrary().addClass(cls);
    return cls;
  }

  /// Returns an [ExtensionTypeDeclaration] node that fits the requirements.
  ///
  /// If no such [ExtensionTypeDeclaration] exists in
  /// [_neededExtensionTypeDeclarations], a new [ExtensionTypeDeclaration] is
  /// created and added to [_neededExtensionTypeDeclarations].
  // TODO(johnniwinther): Add requirements when/where needed.
  ExtensionTypeDeclaration _needExtensionTypeDeclaration() {
    for (ExtensionTypeDeclaration extensionTypeDeclaration
        in _neededExtensionTypeDeclarations) {
      return extensionTypeDeclaration;
    }
    ExtensionTypeDeclaration extensionTypeDeclaration =
        ExtensionTypeDeclaration(
            name: 'foo',
            fileUri: _uri,
            declaredRepresentationType: const DynamicType());
    _neededExtensionTypeDeclarations.add(extensionTypeDeclaration);
    _needLibrary().addExtensionTypeDeclaration(extensionTypeDeclaration);
    return extensionTypeDeclaration;
  }

  /// Returns a [Typedef] node that fits the requirements.
  ///
  /// If no such [Typedef] exists in [_neededTypedefs], a new [Typedef] is
  /// created and added to [_neededTypedefs].
  // TODO(johnniwinther): Add requirements when/where needed.
  Typedef _needTypedef() {
    for (Typedef typedef in _neededTypedefs) {
      return typedef;
    }
    Typedef typedef = Typedef('foo', DynamicType(), fileUri: _uri);
    _neededTypedefs.add(typedef);
    _needLibrary().addTypedef(typedef);
    return typedef;
  }

  /// Returns a [TypeParameter] node that fits the requirements.
  ///
  /// If no such [TypeParameter] exists in [_neededTypeParameters], a new
  /// [TypeParameter] is created and added to [_neededTypeParameters].
  // TODO(johnniwinther): Add requirements when/where needed.
  TypeParameter _needTypeParameter() {
    for (TypeParameter typeParameter in _neededTypeParameters) {
      return typeParameter;
    }
    TypeParameter typeParameter =
        TypeParameter('foo', DynamicType(), DynamicType());
    _neededTypeParameters.add(typeParameter);
    // TODO(johnniwinther): Add the type parameter to a context; class, method
    // or function type.
    return typeParameter;
  }

  /// Returns a [StructuralParameter] node that fits the requirements.
  ///
  /// If no such [StructuralParameter] exists in
  /// [_neededStructuralParameters], a new [StructuralParameter] is
  /// created and added to [_neededStructuralParameters].
  // TODO(johnniwinther): Add requirements when/where needed.
  StructuralParameter _needStructuralParameter() {
    for (StructuralParameter typeParameter in _neededStructuralParameters) {
      return typeParameter;
    }
    StructuralParameter functionTypeTypeParameter =
        StructuralParameter('foo', DynamicType(), DynamicType());
    _neededStructuralParameters.add(functionTypeTypeParameter);
    // TODO(johnniwinther): Add the type parameter to a context, that is,
    // function type.
    return functionTypeTypeParameter;
  }

  /// Returns a [Procedure] node that fits the requirements.
  ///
  /// If no such [Procedure] exists in [_neededProcedures], a new [Library] is
  /// created and added to [_neededProcedures].
  ///
  /// [index] is used to create multiple distinct [Procedure] nodes even when
  /// these have the same requirements.
  Procedure _needProcedure({int? index, bool? isStatic}) {
    for (Procedure procedure in _neededProcedures) {
      if (isStatic == null || isStatic == procedure.isStatic) {
        if (index == null || index == 0) {
          return procedure;
        } else {
          index--;
        }
      }
    }
    isStatic ??= true;
    Procedure procedure = Procedure(
        Name('foo'), ProcedureKind.Method, FunctionNode(Block([])),
        fileUri: _uri, isStatic: isStatic);
    _neededProcedures.add(procedure);
    if (isStatic) {
      _needLibrary().addProcedure(procedure);
    } else {
      _needClass().addProcedure(procedure);
    }
    return procedure;
  }

  /// Returns a [Constructor] node that fits the requirements.
  ///
  /// If no such [Constructor] exists in [_neededConstructors], a new
  /// [Constructor] is created and added to [_neededConstructors].
  // TODO(johnniwinther): Add requirements when/where needed.
  Constructor _needConstructor() {
    for (Constructor constructor in _neededConstructors) {
      return constructor;
    }
    Constructor constructor =
        Constructor(FunctionNode(null), name: Name('foo'), fileUri: _uri);
    _needClass().addConstructor(constructor);
    return constructor;
  }

  /// Returns a redirecting factory [Procedure] node that fits the requirements.
  ///
  /// If no such [Library] exists in [_neededRedirectingFactories], a new
  /// [Procedure] is created and added to [_neededRedirectingFactories].
  // TODO(johnniwinther): Add requirements when/where needed.
  Procedure _needRedirectingFactory() {
    for (Procedure redirectingFactory in _neededRedirectingFactories) {
      return redirectingFactory;
    }
    Procedure redirectingFactory = Procedure(
        Name('foo'),
        ProcedureKind.Method,
        FunctionNode(null)
          ..redirectingFactoryTarget =
              new RedirectingFactoryTarget(_needConstructor(), []),
        fileUri: _uri);
    _needClass().addProcedure(redirectingFactory);
    return redirectingFactory;
  }

  /// Returns a [Field] node that fits the requirements.
  ///
  /// If no such [Field] exists in [_neededFields], a new [Field] is
  /// created and added to [_neededFields].
  ///
  /// [index] is used to create multiple distinct [Field] nodes even when
  /// these have the same requirements.
  Field _needField({int? index, bool? isStatic, bool? hasSetter}) {
    for (Field field in _neededFields) {
      if (isStatic == null ||
          isStatic == field.isStatic && hasSetter == null ||
          hasSetter == field.hasSetter) {
        if (index == null || index == 0) {
          return field;
        } else {
          index--;
        }
      }
    }
    hasSetter ??= false;
    isStatic ??= true;
    Field field = hasSetter
        ? new Field.immutable(Name('foo'), fileUri: _uri, isStatic: isStatic)
        : new Field.mutable(Name('foo'), fileUri: _uri, isStatic: isStatic);
    _neededFields.add(field);
    if (isStatic) {
      _needLibrary().addField(field);
    } else {
      _needClass().addField(field);
    }
    return field;
  }

  /// Returns a [VariableDeclaration] node that fits the requirements.
  ///
  /// If no such [VariableDeclaration] exists in [_neededVariableDeclarations],
  /// a new [VariableDeclaration] is created and added to
  /// [_neededVariableDeclarations].
  // TODO(johnniwinther): Add requirements when/where needed.
  VariableDeclaration _needVariableDeclaration() {
    for (VariableDeclaration variableDeclaration
        in _neededVariableDeclarations) {
      return variableDeclaration;
    }
    VariableDeclaration variableDeclaration = VariableDeclaration('foo');
    _neededVariableDeclarations.add(variableDeclaration);
    return variableDeclaration;
  }

  /// Returns a [LabeledStatement] node that fits the requirements.
  ///
  /// If no such [LabeledStatement] exists in [_neededLabeledStatements], a new
  /// [LabeledStatement] is created and added to [_neededLabeledStatements].
  // TODO(johnniwinther): Add requirements when/where needed.
  LabeledStatement _needLabeledStatement() {
    for (LabeledStatement labeledStatement in _neededLabeledStatements) {
      return labeledStatement;
    }
    LabeledStatement labeledStatement = LabeledStatement(null);
    _neededLabeledStatements.add(labeledStatement);
    return labeledStatement;
  }

  /// Returns a [SwitchCase] node that fits the requirements.
  ///
  /// If no such [SwitchCase] exists in [_neededSwitchCases], a new [SwitchCase]
  /// is created and added to [_neededSwitchCases].
  // TODO(johnniwinther): Add requirements when/where needed.
  SwitchCase _needSwitchCase() {
    for (SwitchCase switchCase in _neededSwitchCases) {
      return switchCase;
    }
    SwitchCase switchCase =
        SwitchCase([NullLiteral()], [TreeNode.noOffset], EmptyStatement());
    _neededSwitchCases.add(switchCase);
    return switchCase;
  }

  /// Returns a [FunctionDeclaration] node that fits the requirements.
  ///
  /// If no such [FunctionDeclaration] exists in [_neededFunctionDeclarations],
  /// a new [FunctionDeclaration] is created and added to
  /// [_neededFunctionDeclarations].
  // TODO(johnniwinther): Add requirements when/where needed.
  FunctionDeclaration _needFunctionDeclaration() {
    for (FunctionDeclaration functionDeclaration
        in _neededFunctionDeclarations) {
      return functionDeclaration;
    }
    FunctionDeclaration functionDeclaration = FunctionDeclaration(
        VariableDeclaration('foo'), FunctionNode(Block([])));
    _neededFunctionDeclarations.add(functionDeclaration);
    return functionDeclaration;
  }

  /// Returns a fresh file offset value.
  int _needFileOffset() => _fileOffset++;

  /// Creates an [Expression] node.
  ///
  /// If there are any pending expressions, one of these is created.
  Expression _createExpression() {
    if (_pendingExpressions.isEmpty) {
      return NullLiteral()..fileOffset = _needFileOffset();
    }
    ExpressionKind kind = _pendingExpressions.keys.first;
    return _createExpressionFromKind(kind);
  }

  /// Creates an [Expression] node of the specified [kind].
  ///
  /// If there are any pending expressions of this [kind], one of these is
  /// created.
  Expression _createExpressionFromKind(ExpressionKind kind) {
    int? index = _pendingExpressions.remove(kind);
    switch (kind) {
      case ExpressionKind.AsExpression:
        return AsExpression(_createExpression(), _createDartType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.AwaitExpression:
        return AwaitExpression(_createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.BlockExpression:
        return BlockExpression(
            _createStatementFromKind(StatementKind.Block) as Block,
            _createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.BoolLiteral:
        return BoolLiteral(true)..fileOffset = _needFileOffset();
      case ExpressionKind.CheckLibraryIsLoaded:
        return CheckLibraryIsLoaded(_needLibraryDependency(deferred: true))
          ..fileOffset = _needFileOffset();
      case ExpressionKind.ConditionalExpression:
        return ConditionalExpression(_createExpression(), _createExpression(),
            _createExpression(), _createDartType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.ConstantExpression:
        return ConstantExpression(_createConstant(), _createDartType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.ConstructorInvocation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => ConstructorInvocation(_needConstructor(), _createArguments(),
              isConst: false)
            ..fileOffset = _needFileOffset(),
          () => ConstructorInvocation(_needConstructor(), _createArguments(),
              isConst: true)
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.ConstructorTearOff:
        return ConstructorTearOff(_needConstructor())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.DoubleLiteral:
        return DoubleLiteral(42.5)..fileOffset = _needFileOffset();
      case ExpressionKind.DynamicGet:
        return DynamicGet(
            DynamicAccessKind.Dynamic, _createExpression(), _createName())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.DynamicInvocation:
        return DynamicInvocation(DynamicAccessKind.Dynamic, _createExpression(),
            _createName(), _createArguments())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.DynamicSet:
        return DynamicSet(DynamicAccessKind.Dynamic, _createExpression(),
            _createName(), _createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.EqualsCall:
        return EqualsCall(_createExpression(), _createExpression(),
            functionType: _createFunctionType(),
            interfaceTarget: _needProcedure())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.EqualsNull:
        return EqualsNull(_createExpression())..fileOffset = _needFileOffset();
      case ExpressionKind.FileUriExpression:
        return FileUriExpression(_createExpression(), _uri)
          ..fileOffset = _needFileOffset();
      case ExpressionKind.FunctionExpression:
        return FunctionExpression(_createFunctionNode())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.FunctionInvocation:
        return FunctionInvocation(FunctionAccessKind.FunctionType,
            _createExpression(), _createArguments(),
            functionType: _createFunctionType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.FunctionTearOff:
        return FunctionTearOff(_createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.InstanceCreation:
        return InstanceCreation(_needClass().reference, [], {}, [], [])
          ..fileOffset = _needFileOffset();
      case ExpressionKind.InstanceGet:
        return InstanceGet(
            InstanceAccessKind.Instance, _createExpression(), _createName(),
            interfaceTarget: _needField(), resultType: _createDartType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.InstanceGetterInvocation:
        return InstanceGetterInvocation(InstanceAccessKind.Instance,
            _createExpression(), _createName(), _createArguments(),
            interfaceTarget: _needField(), functionType: _createFunctionType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.InstanceInvocation:
        return InstanceInvocation(InstanceAccessKind.Instance,
            _createExpression(), _createName(), _createArguments(),
            interfaceTarget: _needProcedure(),
            functionType: _createFunctionType())
          ..fileOffset = _needFileOffset()
          ..isBoundsSafe = true;
      case ExpressionKind.InstanceSet:
        return InstanceSet(InstanceAccessKind.Instance, _createExpression(),
            _createName(), _createExpression(),
            interfaceTarget: _needField())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.InstanceTearOff:
        return InstanceTearOff(
            InstanceAccessKind.Instance, _createExpression(), _createName(),
            interfaceTarget: _needProcedure(), resultType: _createDartType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.Instantiation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => Instantiation(_createExpression(), [])
            ..fileOffset = _needFileOffset(),
          () => Instantiation(_createExpression(), [_createDartType()])
            ..fileOffset = _needFileOffset(),
          () => Instantiation(
              _createExpression(), [_createDartType(), _createDartType()])
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.IntLiteral:
        return IntLiteral(42)..fileOffset = _needFileOffset();
      case ExpressionKind.InvalidExpression:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => InvalidExpression(null)..fileOffset = _needFileOffset(),
          () => InvalidExpression('foo')..fileOffset = _needFileOffset(),
          () => InvalidExpression('foo', _createExpression())
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.IsExpression:
        return IsExpression(
          _createExpression(),
          _createDartType(),
        )..fileOffset = _needFileOffset();
      case ExpressionKind.Let:
        return Let(
            _createStatementFromKind(StatementKind.VariableDeclaration)
                as VariableDeclaration,
            _createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.ListConcatenation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => ListConcatenation([], typeArgument: _createDartType())
            ..fileOffset = _needFileOffset(),
          () => ListConcatenation([_createExpression()],
              typeArgument: _createDartType())
            ..fileOffset = _needFileOffset(),
          () => ListConcatenation([_createExpression(), _createExpression()],
              typeArgument: _createDartType())
            ..fileOffset = _needFileOffset()
        ]);
      case ExpressionKind.ListLiteral:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => ListLiteral([], typeArgument: _createDartType(), isConst: false)
            ..fileOffset = _needFileOffset(),
          () => ListLiteral([_createExpression()],
              typeArgument: _createDartType(), isConst: false)
            ..fileOffset = _needFileOffset(),
          () => ListLiteral([_createExpression(), _createExpression()],
              typeArgument: _createDartType(), isConst: false)
            ..fileOffset = _needFileOffset(),
          () => ListLiteral([_createExpression(), _createExpression()],
              typeArgument: _createDartType(), isConst: true)
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.LoadLibrary:
        return LoadLibrary(_needLibraryDependency(deferred: true))
          ..fileOffset = _needFileOffset();
      case ExpressionKind.LocalFunctionInvocation:
        return LocalFunctionInvocation(
            _needFunctionDeclaration().variable, _createArguments(),
            functionType: _createFunctionType())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.LogicalExpression:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => LogicalExpression(_createExpression(),
              LogicalExpressionOperator.AND, _createExpression())
            ..fileOffset = _needFileOffset(),
          () => LogicalExpression(_createExpression(),
              LogicalExpressionOperator.OR, _createExpression())
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.MapConcatenation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => MapConcatenation([],
              keyType: _createDartType(), valueType: _createDartType())
            ..fileOffset = _needFileOffset(),
          () => MapConcatenation([_createExpression()],
              keyType: _createDartType(), valueType: _createDartType())
            ..fileOffset = _needFileOffset(),
          () => MapConcatenation([_createExpression(), _createExpression()],
              keyType: _createDartType(), valueType: _createDartType())
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.MapLiteral:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => MapLiteral([],
              keyType: _createDartType(),
              valueType: _createDartType(),
              isConst: false)
            ..fileOffset = _needFileOffset(),
          () => MapLiteral([_createMapLiteralEntry()],
              keyType: _createDartType(),
              valueType: _createDartType(),
              isConst: false)
            ..fileOffset = _needFileOffset(),
          () => MapLiteral([
                _createMapLiteralEntry(),
                _createMapLiteralEntry(),
              ],
                  keyType: _createDartType(),
                  valueType: _createDartType(),
                  isConst: false)
                ..fileOffset = _needFileOffset(),
          () => MapLiteral([
                _createMapLiteralEntry(),
                _createMapLiteralEntry(),
              ],
                  keyType: _createDartType(),
                  valueType: _createDartType(),
                  isConst: true)
                ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.Not:
        return Not(_createExpression())..fileOffset = _needFileOffset();
      case ExpressionKind.NullCheck:
        return NullCheck(_createExpression())..fileOffset = _needFileOffset();
      case ExpressionKind.NullLiteral:
        return NullLiteral();
      case ExpressionKind.RedirectingFactoryTearOff:
        return RedirectingFactoryTearOff(_needRedirectingFactory())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.Rethrow:
        return Rethrow()..fileOffset = _needFileOffset();
      case ExpressionKind.SetConcatenation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => SetConcatenation([], typeArgument: _createDartType())
            ..fileOffset = _needFileOffset(),
          () => SetConcatenation([_createExpression()],
              typeArgument: _createDartType())
            ..fileOffset = _needFileOffset(),
          () => SetConcatenation([_createExpression(), _createExpression()],
              typeArgument: _createDartType())
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SetLiteral:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => SetLiteral([], typeArgument: _createDartType(), isConst: false)
            ..fileOffset = _needFileOffset(),
          () => SetLiteral([_createExpression()],
              typeArgument: _createDartType(), isConst: false)
            ..fileOffset = _needFileOffset(),
          () => SetLiteral([_createExpression(), _createExpression()],
              typeArgument: _createDartType(), isConst: false)
            ..fileOffset = _needFileOffset(),
          () => SetLiteral([_createExpression(), _createExpression()],
              typeArgument: _createDartType(), isConst: true)
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.StaticGet:
        return StaticGet(_needField())..fileOffset = _needFileOffset();
      case ExpressionKind.StaticInvocation:
        return StaticInvocation(_needProcedure(), _createArguments())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.StaticSet:
        return StaticSet(_needField(), _createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.StaticTearOff:
        return StaticTearOff(_needProcedure())..fileOffset = _needFileOffset();
      case ExpressionKind.StringConcatenation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => StringConcatenation([])..fileOffset = _needFileOffset(),
          () => StringConcatenation([_createExpression()])
            ..fileOffset = _needFileOffset(),
          () => StringConcatenation([_createExpression(), _createExpression()])
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.StringLiteral:
        return StringLiteral('foo');
      case ExpressionKind.AbstractSuperMethodInvocation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => AbstractSuperMethodInvocation(
              _createName(), _createArguments(), _needProcedure())
            ..fileOffset = _needFileOffset(),
          () => AbstractSuperMethodInvocation(
              _createName(), _createArguments(), _needProcedure())
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SuperMethodInvocation:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => SuperMethodInvocation(
              _createName(), _createArguments(), _needProcedure())
            ..fileOffset = _needFileOffset(),
          () => SuperMethodInvocation(
              _createName(), _createArguments(), _needProcedure())
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.AbstractSuperPropertyGet:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => AbstractSuperPropertyGet(_createName(), _needProcedure())
            ..fileOffset = _needFileOffset(),
          () => AbstractSuperPropertyGet(_createName(), _needField())
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.AbstractSuperPropertySet:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => AbstractSuperPropertySet(
              _createName(), _createExpression(), _needProcedure())
            ..fileOffset = _needFileOffset(),
          () => AbstractSuperPropertySet(
              _createName(), _createExpression(), _needField())
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SuperPropertyGet:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => SuperPropertyGet(_createName(), _needProcedure())
            ..fileOffset = _needFileOffset(),
          () => SuperPropertyGet(_createName(), _needField())
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SuperPropertySet:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => SuperPropertySet(
              _createName(), _createExpression(), _needProcedure())
            ..fileOffset = _needFileOffset(),
          () =>
              SuperPropertySet(_createName(), _createExpression(), _needField())
                ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SymbolLiteral:
        return SymbolLiteral('foo')..fileOffset = _needFileOffset();
      case ExpressionKind.ThisExpression:
        return ThisExpression()..fileOffset = _needFileOffset();
      case ExpressionKind.Throw:
        return Throw(_createExpression())..fileOffset = _needFileOffset();
      case ExpressionKind.TypeLiteral:
        return TypeLiteral(_createDartType())..fileOffset = _needFileOffset();
      case ExpressionKind.TypedefTearOff:
        // TODO(johnniwinther): Add non-trivial cases.
        return TypedefTearOff([], _createExpression(), [])
          ..fileOffset = _needFileOffset();
      case ExpressionKind.VariableGet:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => VariableGet(_needVariableDeclaration())
            ..fileOffset = _needFileOffset(),
          () => VariableGet(_needVariableDeclaration(), _createDartType())
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.VariableSet:
        return VariableSet(_needVariableDeclaration(), _createExpression())
          ..fileOffset = _needFileOffset();
      case ExpressionKind.RecordIndexGet:
        return RecordIndexGet(_createExpression(),
            new RecordType([_createDartType()], [], Nullability.nonNullable), 0)
          ..fileOffset = _needFileOffset();
      case ExpressionKind.RecordNameGet:
        String name = _createName().text;
        return RecordNameGet(
            _createExpression(),
            new RecordType([], [new NamedType(name, _createDartType())],
                Nullability.nonNullable),
            name)
          ..fileOffset = _needFileOffset();
      case ExpressionKind.RecordLiteral:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => RecordLiteral([_createExpression()], [],
              RecordType([_createDartType()], [], Nullability.nonNullable),
              isConst: false)
            ..fileOffset = _needFileOffset(),
          () => RecordLiteral(
              [],
              [NamedExpression('foo', _createExpression())],
              RecordType([], [NamedType('foo', _createDartType())],
                  Nullability.nonNullable),
              isConst: false)
            ..fileOffset = _needFileOffset(),
          () => RecordLiteral(
              [_createExpression()],
              [NamedExpression('foo', _createExpression())],
              RecordType(
                  [_createDartType()],
                  [NamedType('foo', _createDartType())],
                  Nullability.nonNullable),
              isConst: false)
            ..fileOffset = _needFileOffset(),
          () => RecordLiteral([_createExpression()], [],
              RecordType([_createDartType()], [], Nullability.nonNullable),
              isConst: true)
            ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.SwitchExpression:
        return _createOneOf(_pendingExpressions, kind, index, [
          () => new SwitchExpression(_createExpression(), [])
            ..fileOffset = _needFileOffset(),
          () => new SwitchExpression(_createExpression(), [
                _createNodeFromKind(NodeKind.SwitchExpressionCase)
                    as SwitchExpressionCase
              ])
                ..fileOffset = _needFileOffset(),
        ]);
      case ExpressionKind.PatternAssignment:
        return new PatternAssignment(_createPattern(), _createExpression())
          ..fileOffset = _needFileOffset();
    }
  }

  /// Creates an [Pattern] node.
  ///
  /// If there are any pending expressions, one of these is created.
  Pattern _createPattern() {
    if (_pendingPatterns.isEmpty) {
      return ConstantPattern(NullLiteral()..fileOffset = _needFileOffset())
        ..fileOffset = _needFileOffset();
    }
    PatternKind kind = _pendingPatterns.keys.first;
    return _createPatternFromKind(kind);
  }

  /// Creates an [Expression] node of the specified [kind].
  ///
  /// If there are any pending expressions of this [kind], one of these is
  /// created.
  Pattern _createPatternFromKind(PatternKind kind) {
    int? index = _pendingPatterns.remove(kind);
    switch (kind) {
      case PatternKind.AndPattern:
        return AndPattern(_createPattern(), _createPattern())
          ..fileOffset = _needFileOffset();
      case PatternKind.AssignedVariablePattern:
        return AssignedVariablePattern(_needVariableDeclaration())
          ..fileOffset = _needFileOffset();
      case PatternKind.CastPattern:
        return CastPattern(_createPattern(), _createDartType())
          ..fileOffset = _needFileOffset();
      case PatternKind.ConstantPattern:
        return ConstantPattern(_createExpression())
          ..fileOffset = _needFileOffset();
      case PatternKind.NullAssertPattern:
        return NullAssertPattern(_createPattern())
          ..fileOffset = _needFileOffset();
      case PatternKind.NullCheckPattern:
        return NullCheckPattern(_createPattern())
          ..fileOffset = _needFileOffset();
      case PatternKind.InvalidPattern:
        return InvalidPattern(_createExpression(), declaredVariables: [])
          ..fileOffset = _needFileOffset();
      case PatternKind.ListPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => ListPattern(null, [])..fileOffset = _needFileOffset(),
          () => ListPattern(_createDartType(), [_createPattern()])
            ..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.MapPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => MapPattern(null, null, []),
          () => MapPattern(_createDartType(), _createDartType(), [
                _createNodeFromKind(NodeKind.MapPatternEntry) as MapPatternEntry
              ])
                ..fileOffset = _needFileOffset(),
          () => MapPattern(_createDartType(), _createDartType(), [
                _createNodeFromKind(NodeKind.MapPatternEntry)
                    as MapPatternEntry,
                _createNodeFromKind(NodeKind.MapPatternRestEntry)
                    as MapPatternEntry
              ])
                ..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.NamedPattern:
        return NamedPattern('foo', _createPattern())
          ..fileOffset = _needFileOffset();
      case PatternKind.ObjectPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => ObjectPattern(_createDartType(), [])
            ..fileOffset = _needFileOffset(),
          () => ObjectPattern(_createDartType(), [
                _createPatternFromKind(PatternKind.NamedPattern) as NamedPattern
              ])
                ..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.OrPattern:
        return OrPattern(_createPattern(), _createPattern(),
            orPatternJointVariables: [])
          ..fileOffset = _needFileOffset();
      case PatternKind.RecordPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => RecordPattern([])..fileOffset = _needFileOffset(),
          () =>
              RecordPattern([_createPattern()])..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.RelationalPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => RelationalPattern(
              RelationalPatternKind.equals, _createExpression())
            ..fileOffset = _needFileOffset(),
          () => RelationalPattern(
              RelationalPatternKind.lessThan, _createExpression())
            ..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.RestPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => RestPattern(null)..fileOffset = _needFileOffset(),
          () => RestPattern(_createPattern())..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.VariablePattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => VariablePattern(null, _createVariableDeclaration())
            ..fileOffset = _needFileOffset(),
          () => VariablePattern(_createDartType(), _createVariableDeclaration())
            ..fileOffset = _needFileOffset(),
        ]);
      case PatternKind.WildcardPattern:
        return _createOneOf(_pendingPatterns, kind, index, [
          () => WildcardPattern(null)..fileOffset = _needFileOffset(),
          () => WildcardPattern(_createDartType())
            ..fileOffset = _needFileOffset(),
        ]);
    }
  }

  /// Creates a [Statement] node.
  ///
  /// If there are any pending statements, one of these is created.
  Statement _createStatement() {
    if (_pendingStatements.isEmpty) {
      return EmptyStatement()..fileOffset = _needFileOffset();
    }
    StatementKind kind = _pendingStatements.keys.first;
    return _createStatementFromKind(kind);
  }

  /// Creates a [Statement] of the specified [kind].
  ///
  /// If there are any pending statements of this [kind], one of these is
  /// created.
  Statement _createStatementFromKind(StatementKind kind) {
    int? index = _pendingStatements.remove(kind);
    switch (kind) {
      case StatementKind.AssertBlock:
        return _createOneOf(_pendingStatements, kind, index, [
          () => AssertBlock([])..fileOffset = _needFileOffset(),
          () =>
              AssertBlock([_createStatement()])..fileOffset = _needFileOffset(),
          () => AssertBlock([_createStatement(), _createStatement()])
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.AssertStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => AssertStatement(_createExpression(),
              conditionStartOffset: _needFileOffset(),
              conditionEndOffset: _needFileOffset())
            ..fileOffset = _needFileOffset(),
          () => AssertStatement(_createExpression(),
              message: _createExpression(),
              conditionStartOffset: _needFileOffset(),
              conditionEndOffset: _needFileOffset())
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.Block:
        return _createOneOf(_pendingStatements, kind, index, [
          () => Block([])..fileOffset = _needFileOffset(),
          () => Block([_createStatement()])..fileOffset = _needFileOffset(),
          () => Block([_createStatement(), _createStatement()])
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.BreakStatement:
        return BreakStatement(_needLabeledStatement())
          ..fileOffset = _needFileOffset();
      case StatementKind.ContinueSwitchStatement:
        return ContinueSwitchStatement(_needSwitchCase())
          ..fileOffset = _needFileOffset();
      case StatementKind.DoStatement:
        return DoStatement(_createStatement(), _createExpression())
          ..fileOffset = _needFileOffset();
      case StatementKind.EmptyStatement:
        return EmptyStatement()..fileOffset = _needFileOffset();
      case StatementKind.ExpressionStatement:
        return ExpressionStatement(_createExpression())
          ..fileOffset = _needFileOffset();
      case StatementKind.ForInStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => ForInStatement(_createVariableDeclaration(),
              _createExpression(), _createStatement(),
              isAsync: false)
            ..fileOffset = _needFileOffset(),
          () => ForInStatement(_createVariableDeclaration(),
              _createExpression(), _createStatement(),
              isAsync: true)
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.ForStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => ForStatement([], null, [], _createStatement())
            ..fileOffset = _needFileOffset(),
          () => ForStatement([_createVariableDeclaration()],
              _createExpression(), [_createExpression()], _createStatement())
            ..fileOffset = _needFileOffset(),
          () => ForStatement(
              [_createVariableDeclaration(), _createVariableDeclaration()],
              _createExpression(),
              [_createExpression(), _createExpression()],
              _createStatement())
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.FunctionDeclaration:
        return FunctionDeclaration(
            VariableDeclaration(null, isSynthesized: true),
            _createFunctionNode())
          ..fileOffset = _needFileOffset();
      case StatementKind.IfStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => IfStatement(_createExpression(), _createStatement(), null)
            ..fileOffset = _needFileOffset(),
          () => IfStatement(
              _createExpression(), _createStatement(), _createStatement())
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.LabeledStatement:
        return LabeledStatement(_createStatement())
          ..fileOffset = _needFileOffset();
      case StatementKind.ReturnStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => ReturnStatement()..fileOffset = _needFileOffset(),
          () => ReturnStatement(_createExpression())
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.SwitchStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => SwitchStatement(_createExpression(), [])
            ..fileOffset = _needFileOffset(),
          () => SwitchStatement(_createExpression(), [_createSwitchCase()])
            ..fileOffset = _needFileOffset(),
          () => SwitchStatement(
              _createExpression(), [_createSwitchCase(), _createSwitchCase()])
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.TryCatch:
        return _createOneOf(_pendingStatements, kind, index, [
          () =>
              TryCatch(_createStatement(), [])..fileOffset = _needFileOffset(),
          () => TryCatch(_createStatement(), [_createCatch()])
            ..fileOffset = _needFileOffset(),
          () => TryCatch(_createStatement(), [_createCatch(), _createCatch()])
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.TryFinally:
        return TryFinally(_createStatement(), _createStatement())
          ..fileOffset = _needFileOffset();
      case StatementKind.VariableDeclaration:
        return _createOneOf(_pendingStatements, kind, index, [
          () => VariableDeclaration('foo')..fileOffset = _needFileOffset(),
          () => VariableDeclaration('foo', initializer: _createExpression())
            ..fileOffset = _needFileOffset(),
          () => VariableDeclaration('foo', type: _createDartType())
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.WhileStatement:
        return WhileStatement(_createExpression(), _createStatement())
          ..fileOffset = _needFileOffset();
      case StatementKind.YieldStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => YieldStatement(_createExpression(), isYieldStar: false)
            ..fileOffset = _needFileOffset(),
          () => YieldStatement(_createExpression(), isYieldStar: true)
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.PatternSwitchStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => PatternSwitchStatement(_createExpression(), [])
            ..fileOffset = _needFileOffset(),
          () => PatternSwitchStatement(_createExpression(), [
                _createNodeFromKind(NodeKind.PatternSwitchCase)
                    as PatternSwitchCase
              ])
                ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.IfCaseStatement:
        return _createOneOf(_pendingStatements, kind, index, [
          () => IfCaseStatement(
              _createExpression(),
              _createNodeFromKind(NodeKind.PatternGuard) as PatternGuard,
              _createStatement())
            ..fileOffset = _needFileOffset(),
          () => IfCaseStatement(
              _createExpression(),
              _createNodeFromKind(NodeKind.PatternGuard) as PatternGuard,
              _createStatement(),
              _createStatement())
            ..fileOffset = _needFileOffset(),
        ]);
      case StatementKind.PatternVariableDeclaration:
        return _createOneOf(_pendingStatements, kind, index, [
          () => new PatternVariableDeclaration(
              _createPattern(), _createExpression(),
              isFinal: false)
            ..fileOffset = _needFileOffset(),
          () => new PatternVariableDeclaration(
              _createPattern(), _createExpression(),
              isFinal: true)
            ..fileOffset = _needFileOffset(),
        ]);
    }
  }

  /// Creates a [VariableDeclaration] node.
  ///
  /// If there are any pending [VariableDeclaration] nodes, one of these is
  /// created.
  VariableDeclaration _createVariableDeclaration() {
    return _createStatementFromKind(StatementKind.VariableDeclaration)
        as VariableDeclaration;
  }

  /// Creates a [DartType] node.
  ///
  /// If there are any pending types, one of these is created.
  DartType _createDartType() {
    if (_pendingDartTypes.isEmpty) {
      return VoidType();
    }
    DartTypeKind kind = _pendingDartTypes.keys.first;
    return _createDartTypeFromKind(kind);
  }

  /// Creates a [DartType] node of the specified [kind].
  ///
  /// If there are any pending types of this [kind], one of these is created.
  DartType _createDartTypeFromKind(DartTypeKind kind) {
    int? index = _pendingDartTypes.remove(kind);
    switch (kind) {
      case DartTypeKind.DynamicType:
        return DynamicType();
      case DartTypeKind.FunctionType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          // TODO(johnniwinther): Create non-trivial cases.
          () => FunctionType([], _createDartType(), Nullability.nonNullable),
        ]);
      case DartTypeKind.RecordType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          // TODO(cstefantsova): Create non-trivial cases.
          () => RecordType([], [], Nullability.nonNullable),
        ]);
      case DartTypeKind.FutureOrType:
        return FutureOrType(_createDartType(), Nullability.nonNullable);
      case DartTypeKind.InterfaceType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          // TODO(johnniwinther): Create non-trivial cases.
          () => InterfaceType(_needClass(), Nullability.nonNullable, []),
        ]);
      case DartTypeKind.InvalidType:
        return InvalidType();
      case DartTypeKind.NeverType:
        return NeverType.nonNullable();
      case DartTypeKind.NullType:
        return NullType();
      case DartTypeKind.TypeParameterType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          () =>
              TypeParameterType(_needTypeParameter(), Nullability.nonNullable),
        ]);
      case DartTypeKind.StructuralParameterType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          () => StructuralParameterType(
              _needStructuralParameter(), Nullability.nonNullable),
        ]);
      case DartTypeKind.IntersectionType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          () => IntersectionType(
              TypeParameterType(_needTypeParameter(), Nullability.nonNullable),
              _createDartType()),
        ]);
      case DartTypeKind.TypedefType:
        return _createOneOf(_pendingDartTypes, kind, index, [
          // TODO(johnniwinther): Create non-trivial cases.
          () => TypedefType(_needTypedef(), Nullability.nonNullable, []),
        ]);
      case DartTypeKind.ExtensionType:
        return ExtensionType(
            _needExtensionTypeDeclaration(), Nullability.nonNullable);
      case DartTypeKind.VoidType:
        return VoidType();
    }
  }

  /// Creates a [FunctionType] node.
  ///
  /// If there are any pending [FunctionType] nodes, one of these is created.
  FunctionType _createFunctionType() {
    return _createDartTypeFromKind(DartTypeKind.FunctionType) as FunctionType;
  }

  /// Creates a [Constant] node.
  ///
  /// If there are any pending constants, one of these is created.
  Constant _createConstant() {
    if (_pendingConstants.isEmpty) {
      return NullConstant();
    }
    ConstantKind kind = _pendingConstants.keys.first;
    return _createConstantFromKind(kind);
  }

  /// Creates a [Constant] node of the specified [kind].
  ///
  /// If there are any pending constants of this [kind], one of these is
  /// created.
  Constant _createConstantFromKind(ConstantKind kind) {
    int? index = _pendingConstants.remove(kind);
    switch (kind) {
      case ConstantKind.BoolConstant:
        return BoolConstant(true);
      case ConstantKind.ConstructorTearOffConstant:
        return ConstructorTearOffConstant(_needConstructor());
      case ConstantKind.DoubleConstant:
        return DoubleConstant(42.5);
      case ConstantKind.InstanceConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => InstanceConstant(_needClass().reference, [], {}),
          () => InstanceConstant(_needClass().reference, [
                _createDartType()
              ], {
                _needField(isStatic: false, hasSetter: false).getterReference:
                    _createConstant()
              }),
          () => InstanceConstant(_needClass().reference, [
                _createDartType()
              ], {
                _needField(index: 0, isStatic: false, hasSetter: false)
                    .getterReference: _createConstant(),
                _needField(index: 1, isStatic: false, hasSetter: false)
                    .getterReference: _createConstant()
              }),
        ]);
      case ConstantKind.InstantiationConstant:
        return InstantiationConstant(_createConstant(), [_createDartType()]);
      case ConstantKind.IntConstant:
        return IntConstant(42);
      case ConstantKind.ListConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => ListConstant(_createDartType(), []),
          () => ListConstant(_createDartType(), [_createConstant()]),
          () => ListConstant(
              _createDartType(), [_createConstant(), _createConstant()]),
        ]);
      case ConstantKind.MapConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => MapConstant(_createDartType(), _createDartType(), []),
          () => MapConstant(_createDartType(), _createDartType(),
              [ConstantMapEntry(_createConstant(), _createConstant())]),
          () => MapConstant(_createDartType(), _createDartType(), [
                ConstantMapEntry(_createConstant(), _createConstant()),
                ConstantMapEntry(_createConstant(), _createConstant())
              ]),
        ]);
      case ConstantKind.RecordConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => RecordConstant(
              [], {}, RecordType([], [], Nullability.nonNullable)),
          () => RecordConstant(
              [_createConstant(), _createConstant()],
              {},
              RecordType([_createDartType(), _createDartType()], [],
                  Nullability.nonNullable)),
          () => RecordConstant(
                  [],
                  {
                    'a': _createConstant(),
                    'b': _createConstant(),
                  },
                  RecordType([], [
                    NamedType('a', _createDartType()),
                    NamedType('b', _createDartType())
                  ], Nullability.nonNullable)),
          () => RecordConstant(
              [_createConstant()],
              {'a': _createConstant()},
              RecordType(
                  [_createDartType()],
                  [NamedType('a', _createDartType())],
                  Nullability.nonNullable)),
        ]);
      case ConstantKind.NullConstant:
        return NullConstant();
      case ConstantKind.RedirectingFactoryTearOffConstant:
        return RedirectingFactoryTearOffConstant(_needRedirectingFactory());
      case ConstantKind.SetConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => SetConstant(_createDartType(), []),
          () => SetConstant(_createDartType(), [_createConstant()]),
          () => SetConstant(
              _createDartType(), [_createConstant(), _createConstant()]),
        ]);
      case ConstantKind.StaticTearOffConstant:
        return StaticTearOffConstant(_needProcedure());
      case ConstantKind.StringConstant:
        return StringConstant('foo');
      case ConstantKind.SymbolConstant:
        return _createOneOf(_pendingConstants, kind, index, [
          () => SymbolConstant('foo', null),
          () => SymbolConstant('_foo', _needLibrary().reference),
        ]);
      case ConstantKind.TypeLiteralConstant:
        return TypeLiteralConstant(_createDartType());
      case ConstantKind.TypedefTearOffConstant:
        // TODO(johnniwinther): Add non-trivial cases.
        return TypedefTearOffConstant(
            [],
            _createConstantFromKind(ConstantKind.ConstructorTearOffConstant)
                as TearOffConstant,
            []);
      case ConstantKind.UnevaluatedConstant:
        return UnevaluatedConstant(_createExpression());
    }
  }

  /// Creates an [Initializer] node.
  ///
  /// If there are any pending initializers, one of these is created.
  Initializer _createInitializer() {
    if (_pendingInitializers.isEmpty) {
      return InvalidInitializer()..fileOffset = _needFileOffset();
    }
    InitializerKind kind = _pendingInitializers.keys.first;
    return _createInitializerFromKind(kind);
  }

  /// Creates an [Initializer] node of the specified [kind].
  ///
  /// If there are any pending initializers of this [kind], one of these is
  /// created.
  Initializer _createInitializerFromKind(InitializerKind kind) {
    // ignore: unused_local_variable
    int? index = _pendingInitializers.remove(kind);
    switch (kind) {
      case InitializerKind.AssertInitializer:
        return AssertInitializer(
            _createStatementFromKind(StatementKind.AssertStatement)
                as AssertStatement)
          ..fileOffset = _needFileOffset();
      case InitializerKind.FieldInitializer:
        return FieldInitializer(
            _needField(isStatic: false), _createExpression())
          ..fileOffset = _needFileOffset();
      case InitializerKind.InvalidInitializer:
        return InvalidInitializer()..fileOffset = _needFileOffset();
      case InitializerKind.LocalInitializer:
        return LocalInitializer(_createVariableDeclaration())
          ..fileOffset = _needFileOffset();
      case InitializerKind.RedirectingInitializer:
        return RedirectingInitializer(_needConstructor(), _createArguments())
          ..fileOffset = _needFileOffset();
      case InitializerKind.SuperInitializer:
        return SuperInitializer(_needConstructor(), _createArguments())
          ..fileOffset = _needFileOffset();
    }
  }

  /// Creates a [Member] node.
  ///
  /// If there are any pending members, one of these is created.
  Member _createMember() {
    if (_pendingMembers.isEmpty) {
      return Field.immutable(_createName(), fileUri: _uri)
        ..fileOffset = _needFileOffset();
    }
    MemberKind kind = _pendingMembers.keys.first;
    return _createMemberKind(kind);
  }

  /// Creates a [Member] node of the specified [kind].
  ///
  /// If there are any pending members of this [kind], one of these is created.
  Member _createMemberKind(MemberKind kind) {
    int? index = _pendingMembers.remove(kind);
    switch (kind) {
      case MemberKind.Constructor:
        return Constructor(_createFunctionNode(),
            name: _createName(), fileUri: _uri)
          ..fileOffset = _needFileOffset();
      case MemberKind.Field:
        return _createOneOf(_pendingMembers, kind, index, [
          () => Field.mutable(_createName(), fileUri: _uri)
            ..fileOffset = _needFileOffset(),
          () => Field.immutable(_createName(), fileUri: _uri)
            ..fileOffset = _needFileOffset(),
        ]);
      case MemberKind.Procedure:
        return _createOneOf(_pendingMembers, kind, index, [
          () => Procedure(
              _createName(), ProcedureKind.Method, _createFunctionNode(),
              fileUri: _uri)
            ..fileOffset = _needFileOffset(),
          () => Procedure(
              _createName(), ProcedureKind.Operator, _createFunctionNode(),
              fileUri: _uri)
            ..fileOffset = _needFileOffset(),
          () => Procedure(
              _createName(), ProcedureKind.Getter, _createFunctionNode(),
              fileUri: _uri)
            ..fileOffset = _needFileOffset(),
          () => Procedure(
              _createName(), ProcedureKind.Setter, _createFunctionNode(),
              fileUri: _uri)
            ..fileOffset = _needFileOffset(),
        ]);
    }
  }

  /// Creates an [Arguments] node.
  ///
  /// If there are any pending [Arguments] nodes, one of these is created.
  Arguments _createArguments() {
    return _createNodeFromKind(NodeKind.Arguments) as Arguments;
  }

  /// Creates a [Name] node.
  ///
  /// If there are any pending [Name] nodes, one of these is created.
  Name _createName() {
    return _createNodeFromKind(NodeKind.Name) as Name;
  }

  /// Creates a [FunctionNode] node.
  ///
  /// If there are any pending [FunctionNode] nodes, one of these is created.
  FunctionNode _createFunctionNode() {
    return _createNodeFromKind(NodeKind.FunctionNode) as FunctionNode;
  }

  /// Creates a [MapLiteralEntry] node.
  ///
  /// If there are any pending [MapLiteralEntry] nodes, one of these is created.
  MapLiteralEntry _createMapLiteralEntry() {
    return _createNodeFromKind(NodeKind.MapLiteralEntry) as MapLiteralEntry;
  }

  /// Creates a [SwitchCase] node.
  ///
  /// If there are any pending [SwitchCase] nodes, one of these is created.
  SwitchCase _createSwitchCase() {
    return _createNodeFromKind(NodeKind.SwitchCase) as SwitchCase;
  }

  /// Creates a [Catch] node.
  ///
  /// If there are any pending [Catch] nodes, one of these is created.
  Catch _createCatch() {
    return _createNodeFromKind(NodeKind.Catch) as Catch;
  }

  /// Creates a [Node] of the specified [kind].
  ///
  /// If there are any pending nodes of this [kind], one of these is created.
  Node _createNodeFromKind(NodeKind kind) {
    int? index = _pendingNodes.remove(kind);
    switch (kind) {
      case NodeKind.Arguments:
        return _createOneOf(_pendingNodes, kind, index, [
          // TODO(johnniwinther): Add non-trivial cases.
          () => Arguments([])..fileOffset = _needFileOffset(),
        ]);
      case NodeKind.Catch:
        // TODO(johnniwinther): Add non-trivial cases.
        return Catch(null, _createStatement())..fileOffset = _needFileOffset();
      case NodeKind.Class:
        return Class(name: 'foo', fileUri: _uri)
          ..fileOffset = _needFileOffset();
      case NodeKind.Combinator:
        return _createOneOf(_pendingNodes, kind, index, [
          () => Combinator.show([])..fileOffset = _needFileOffset(),
          () => Combinator.show(['foo'])..fileOffset = _needFileOffset(),
          () => Combinator.show(['foo', 'bar'])..fileOffset = _needFileOffset(),
          () => Combinator.hide([])..fileOffset = _needFileOffset(),
          () => Combinator.hide(['foo'])..fileOffset = _needFileOffset(),
          () => Combinator.hide(['foo', 'bar'])..fileOffset = _needFileOffset(),
        ]);
      case NodeKind.Component:
        return _component;
      case NodeKind.Extension:
        // TODO(johnniwinther): Add non-trivial cases.
        return Extension(name: 'foo', fileUri: _uri)
          ..fileOffset = _needFileOffset()
          ..onType = _createDartType();
      case NodeKind.FunctionNode:
        // TODO(johnniwinther): Add non-trivial cases.
        return FunctionNode(_createStatement())..fileOffset = _needFileOffset();
      case NodeKind.Library:
        return Library(_uri, fileUri: _uri)..fileOffset = _needFileOffset();
      case NodeKind.LibraryDependency:
        return _createOneOf(_pendingNodes, kind, index, [
          // TODO(johnniwinther): Add more cases.
          () => LibraryDependency.import(_needLibrary())
            ..fileOffset = _needFileOffset(),
          () => LibraryDependency.import(_needLibrary(), name: 'foo')
            ..fileOffset = _needFileOffset(),
          () => LibraryDependency.export(_needLibrary())
            ..fileOffset = _needFileOffset(),
        ]);
      case NodeKind.LibraryPart:
        // TODO(johnniwinther): Add non-trivial cases.
        // TODO(johnniwinther): Do we need to use a valid part uri?
        return LibraryPart([], 'foo')..fileOffset = _needFileOffset();
      case NodeKind.MapLiteralEntry:
        return MapLiteralEntry(_createExpression(), _createExpression())
          ..fileOffset = _needFileOffset();
      case NodeKind.Name:
        return _createOneOf(_pendingNodes, kind, index, [
          () => Name('foo'),
          () => Name('_foo', _needLibrary()),
        ]);
      case NodeKind.NamedExpression:
        return NamedExpression('foo', _createExpression())
          ..fileOffset = _needFileOffset();
      case NodeKind.NamedType:
        return NamedType('foo', _createDartType());
      case NodeKind.Supertype:
        return _createOneOf(_pendingNodes, kind, index, [
          () => Supertype(_needClass(), []),
          () => Supertype(_needClass(), [_createDartType()]),
          () => Supertype(_needClass(), [_createDartType(), _createDartType()]),
        ]);
      case NodeKind.SwitchCase:
        // TODO(johnniwinther): Add non-trivial cases.
        return SwitchCase(
            [NullLiteral()], [TreeNode.noOffset], _createStatement())
          ..fileOffset = _needFileOffset();
      case NodeKind.TypeParameter:
        return TypeParameter('foo', _createDartType(), _createDartType())
          ..fileOffset = _needFileOffset();
      case NodeKind.StructuralParameter:
        return StructuralParameter('foo', _createDartType(), _createDartType());
      case NodeKind.Typedef:
        return Typedef('foo', _createDartType(), fileUri: _uri)
          ..fileOffset = _needFileOffset();
      case NodeKind.ExtensionTypeDeclaration:
        // TODO(johnniwinther): Add non-trivial cases.
        return ExtensionTypeDeclaration(name: 'foo', fileUri: _uri)
          ..fileOffset = _needFileOffset()
          ..declaredRepresentationType = _createDartType();
      case NodeKind.MapPatternEntry:
        return MapPatternEntry(_createExpression(), _createPattern())
          ..fileOffset = _needFileOffset();
      case NodeKind.MapPatternRestEntry:
        return MapPatternRestEntry()..fileOffset = _needFileOffset();
      case NodeKind.PatternGuard:
        return _createOneOf(_pendingNodes, kind, index, [
          () => new PatternGuard(_createPattern())
            ..fileOffset = _needFileOffset(),
          () => new PatternGuard(_createPattern(), _createExpression())
            ..fileOffset = _needFileOffset(),
        ]);
      case NodeKind.PatternSwitchCase:
        return _createOneOf(_pendingNodes, kind, index, [
          () => new PatternSwitchCase([], [], _createStatement(),
              isDefault: true,
              hasLabel: false,
              jointVariables: [],
              jointVariableFirstUseOffsets: null),
          () => new PatternSwitchCase(
              [0],
              [_createNodeFromKind(NodeKind.PatternGuard) as PatternGuard],
              _createStatement(),
              isDefault: false,
              hasLabel: true,
              jointVariables: [],
              jointVariableFirstUseOffsets: null),
        ]);
      case NodeKind.SwitchExpressionCase:
        return new SwitchExpressionCase(
            _createNodeFromKind(NodeKind.PatternGuard) as PatternGuard,
            _createExpression())
          ..fileOffset = _needFileOffset();
    }
  }

  /// Helper that creates a node of type [V] using the list of [creators].
  ///
  /// The [index] indicates how many nodes of the [kind] that have currently
  /// been created. If there are more [creators] left after having created the
  /// [index]th node, [pending] is updated with the next pending index. If all
  /// pending nodes of the given [kind] have been created, [index] is `null` and
  /// the first [creators] function is used.
  V _createOneOf<K, V>(
      Map<K, int> pending, K kind, int? index, List<V Function()> creators) {
    if (index == null) {
      // All pending nodes have been created so we just create the first.
      return creators[0]();
    }
    if (index + 1 < creators.length) {
      pending[kind] = index + 1;
    }
    return creators[index]();
  }
}

/// [NodeKind]s for nodes that can occur inside member bodies.
const Set<NodeKind> inBodyNodeKinds = {
  NodeKind.Arguments,
  NodeKind.Catch,
  NodeKind.FunctionNode,
  NodeKind.MapLiteralEntry,
  NodeKind.MapPatternEntry,
  NodeKind.MapPatternRestEntry,
  NodeKind.Name,
  NodeKind.NamedExpression,
  NodeKind.NamedType,
  NodeKind.SwitchCase,
  NodeKind.TypeParameter,
  NodeKind.PatternGuard,
  NodeKind.PatternSwitchCase,
  NodeKind.SwitchExpressionCase,
};
