// 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.

import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';

/// A collection of factory methods which may be used to create concrete
/// instances of the interfaces that constitute the AST.
///
/// Clients should not extend, implement or mix-in this class.
abstract class AstFactory {
  /// Returns a newly created list of adjacent strings. To be syntactically
  /// valid, the list of [strings] must contain at least two elements.
  AdjacentStrings adjacentStrings(List<StringLiteral> strings);

  /// Returns a newly created annotation. Both the [period] and the
  /// [constructorName] can be `null` if the annotation is not referencing a
  /// named constructor. The [arguments] can be `null` if the annotation is not
  /// referencing a constructor.
  ///
  /// Note that type arguments are only valid if [Feature.generic_metadata] is
  /// enabled.
  Annotation annotation(
      {required Token atSign,
      required Identifier name,
      TypeArgumentList? typeArguments,
      Token? period,
      SimpleIdentifier? constructorName,
      ArgumentList? arguments});

  /// Returns a newly created list of arguments. The list of [arguments] can
  /// be `null` if there are no arguments.
  ArgumentList argumentList(Token leftParenthesis, List<Expression> arguments,
      Token rightParenthesis);

  /// Returns a newly created as expression.
  AsExpression asExpression(
      Expression expression, Token asOperator, TypeAnnotation type);

  /// Returns a newly created assert initializer. The [comma] and [message]
  /// can be `null` if there is no message.
  AssertInitializer assertInitializer(
      Token assertKeyword,
      Token leftParenthesis,
      Expression condition,
      Token? comma,
      Expression? message,
      Token rightParenthesis);

  /// Returns a newly created assert statement. The [comma] and [message] can
  /// be `null` if there is no message.
  AssertStatement assertStatement(
      Token assertKeyword,
      Token leftParenthesis,
      Expression condition,
      Token? comma,
      Expression? message,
      Token rightParenthesis,
      Token semicolon);

  /// Returns a newly created assignment expression.
  AssignmentExpression assignmentExpression(
      Expression leftHandSide, Token operator, Expression rightHandSide);

  /// Returns a newly created await expression.
  AwaitExpression awaitExpression(Token awaitKeyword, Expression expression);

  /// Returns a newly created binary expression.
  BinaryExpression binaryExpression(
      Expression leftOperand, Token operator, Expression rightOperand);

  /// Returns a newly created block of code.
  Block block(
      Token leftBracket, List<Statement> statements, Token rightBracket);

  /// Returns a block comment consisting of the given [tokens].
  Comment blockComment(List<Token> tokens);

  /// Returns a newly created function body consisting of a block of
  /// statements. The [keyword] can be `null` if there is no keyword specified
  /// for the block. The [star] can be `null` if there is no star following the
  /// keyword (and must be `null` if there is no keyword).
  BlockFunctionBody blockFunctionBody(Token? keyword, Token? star, Block block);

  /// Returns a newly created boolean literal.
  BooleanLiteral booleanLiteral(Token literal, bool value);

  /// Returns a newly created break statement. The [label] can be `null` if
  /// there is no label associated with the statement.
  BreakStatement breakStatement(
      Token breakKeyword, SimpleIdentifier? label, Token semicolon);

  /// Returns a newly created cascade expression. The list of
  /// [cascadeSections] must contain at least one element.
  CascadeExpression cascadeExpression(
      Expression target, List<Expression> cascadeSections);

  /// Returns a newly created catch clause. The [onKeyword] and [exceptionType]
  /// can be `null` if the clause will catch all exceptions. The [comma] and
  /// [stackTraceParameter] can be `null` if the stack trace parameter is not
  /// defined.
  CatchClause catchClause(
      Token? onKeyword,
      TypeAnnotation? exceptionType,
      Token? catchKeyword,
      Token? leftParenthesis,
      SimpleIdentifier? exceptionParameter,
      Token? comma,
      SimpleIdentifier? stackTraceParameter,
      Token? rightParenthesis,
      Block body);

  /// Returns a newly created class declaration. Either or both of the
  /// [comment] and [metadata] can be `null` if the class does not have the
  /// corresponding attribute. The [abstractKeyword] can be `null` if the class
  /// is not abstract. The [macroKeyword] can be `null` if the class is not a
  /// macro class. The [augmentKeyword] can be `null` if the class is not an
  /// augmentation class. The [typeParameters] can be `null` if the class does
  /// not have any type parameters. Any or all of the [extendsClause],
  /// [withClause], and [implementsClause] can be `null` if the class does not
  /// have the corresponding clause. The list of [members] can be `null` if the
  /// class does not have any members.
  ClassDeclaration classDeclaration(
      Comment? comment,
      List<Annotation>? metadata,
      Token? abstractKeyword,
      Token? macroKeyword,
      Token? augmentKeyword,
      Token classKeyword,
      SimpleIdentifier name,
      TypeParameterList? typeParameters,
      ExtendsClause? extendsClause,
      WithClause? withClause,
      ImplementsClause? implementsClause,
      Token leftBracket,
      List<ClassMember> members,
      Token rightBracket);

  /// Returns a newly created class type alias. Either or both of the [comment]
  /// and [metadata] can be `null` if the class type alias does not have the
  /// corresponding attribute. The [typeParameters] can be `null` if the class
  /// does not have any type parameters. The [abstractKeyword] can be `null` if
  /// the class is not abstract. The [macroKeyword] can be `null` if the class
  /// is not a macro class. The [augmentKeyword] can be `null` if the class is
  /// not an augmentation class.  The [implementsClause] can be `null` if the
  /// class does not implement any interfaces.
  ClassTypeAlias classTypeAlias(
      Comment? comment,
      List<Annotation>? metadata,
      Token keyword,
      SimpleIdentifier name,
      TypeParameterList? typeParameters,
      Token equals,
      Token? abstractKeyword,
      Token? macroKeyword,
      Token? augmentKeyword,
      NamedType superclass,
      WithClause withClause,
      ImplementsClause? implementsClause,
      Token semicolon);

  /// Returns a newly created reference to a Dart element. The [newKeyword]
  /// can be `null` if the reference is not to a constructor.
  CommentReference commentReference(
      Token? newKeyword, CommentReferableExpression expression);

  /// Returns a newly created compilation unit to have the given directives and
  /// declarations.  The [scriptTag] can be `null` (or omitted) if there is no
  /// script tag in the compilation unit.  The list of [declarations] can be
  /// `null` (or omitted) if there are no directives in the compilation unit.
  /// The list of `declarations` can be `null` (or omitted) if there are no
  /// declarations in the compilation unit.
  CompilationUnit compilationUnit(
      {required Token beginToken,
      ScriptTag? scriptTag,
      List<Directive>? directives,
      List<CompilationUnitMember>? declarations,
      required Token endToken,
      required FeatureSet featureSet});

  /// Returns a newly created conditional expression.
  ConditionalExpression conditionalExpression(
      Expression condition,
      Token question,
      Expression thenExpression,
      Token colon,
      Expression elseExpression);

  /// Returns a newly created configuration.
  Configuration configuration(
      Token ifKeyword,
      Token leftParenthesis,
      DottedName name,
      Token? equalToken,
      StringLiteral? value,
      Token rightParenthesis,
      StringLiteral libraryUri);

  /// Returns a newly created constructor declaration. The [externalKeyword]
  /// can be `null` if the constructor is not external. Either or both of the
  /// [comment] and [metadata] can be `null` if the constructor does not have
  /// the corresponding attribute. The [constKeyword] can be `null` if the
  /// constructor cannot be used to create a constant. The [factoryKeyword] can
  /// be `null` if the constructor is not a factory. The [period] and [name] can
  /// both be `null` if the constructor is not a named constructor. The
  /// [separator] can be `null` if the constructor does not have any
  /// initializers and does not redirect to a different constructor. The list of
  /// [initializers] can be `null` if the constructor does not have any
  /// initializers. The [redirectedConstructor] can be `null` if the constructor
  /// does not redirect to a different constructor.
  ConstructorDeclaration constructorDeclaration(
      Comment? comment,
      List<Annotation>? metadata,
      Token? externalKeyword,
      Token? constKeyword,
      Token? factoryKeyword,
      Identifier returnType,
      Token? period,
      SimpleIdentifier? name,
      FormalParameterList parameters,
      Token? separator,
      List<ConstructorInitializer>? initializers,
      ConstructorName? redirectedConstructor,
      FunctionBody body);

  /// Returns a newly created field initializer to initialize the field with
  /// the given name to the value of the given expression. The [thisKeyword] and
  /// [period] can be `null` if the 'this' keyword was not specified.
  ConstructorFieldInitializer constructorFieldInitializer(
      Token? thisKeyword,
      Token? period,
      SimpleIdentifier fieldName,
      Token equals,
      Expression expression);

  /// Returns a newly created constructor name. The [period] and [name] can be
  /// `null` if the constructor being named is the unnamed constructor.
  ConstructorName constructorName(
      NamedType type, Token? period, SimpleIdentifier? name);

  /// Returns a newly created constructor reference.
  ConstructorReference constructorReference(
      {required ConstructorName constructorName});

  /// Returns a newly created continue statement. The [label] can be `null` if
  /// there is no label associated with the statement.
  ContinueStatement continueStatement(
      Token continueKeyword, SimpleIdentifier? label, Token semicolon);

  /// Returns a newly created formal parameter. Either or both of the
  /// [comment] and [metadata] can be `null` if the declaration does not have
  /// the corresponding attribute. The [keyword] can be `null` if a type name is
  /// given. The [type] must be `null` if the keyword is 'var'.
  DeclaredIdentifier declaredIdentifier(
      Comment? comment,
      List<Annotation>? metadata,
      Token? keyword,
      TypeAnnotation? type,
      SimpleIdentifier identifier);

  /// Returns a newly created default formal parameter. The [separator] and
  /// [defaultValue] can be `null` if there is no default value.
  DefaultFormalParameter defaultFormalParameter(NormalFormalParameter parameter,
      ParameterKind kind, Token? separator, Expression? defaultValue);

  /// Returns a documentation comment consisting of the given [tokens] and
  /// having the given [references] (if supplied) embedded within it.
  Comment documentationComment(List<Token> tokens,
      [List<CommentReference> references]);

  /// Returns a newly created do loop.
  DoStatement doStatement(
      Token doKeyword,
      Statement body,
      Token whileKeyword,
      Token leftParenthesis,
      Expression condition,
      Token rightParenthesis,
      Token semicolon);

  /// Returns a newly created dotted name.
  DottedName dottedName(List<SimpleIdentifier> components);

  /// Returns a newly created floating point literal.
  DoubleLiteral doubleLiteral(Token literal, double value);

  /// Returns a newly created function body.
  EmptyFunctionBody emptyFunctionBody(Token semicolon);

  /// Returns a newly created empty statement.
  EmptyStatement emptyStatement(Token semicolon);

  /// Returns an end-of-line comment consisting of the given [tokens].
  Comment endOfLineComment(List<Token> tokens);

  /// Returns a newly created enum constant declaration. Either or both of the
  /// [comment] and [metadata] can be `null` if the constant does not have the
  /// corresponding attribute. (Technically, enum constants cannot have
  /// metadata, but we allow it for consistency.)
  EnumConstantDeclaration enumConstantDeclaration(
      Comment? comment, List<Annotation>? metadata, SimpleIdentifier name);

  /// Returns a newly created enumeration declaration. Either or both of the
  /// [comment] and [metadata] can be `null` if the declaration does not have
  /// the corresponding attribute. The list of [constants] must contain at least
  /// one value.
  @Deprecated('Use enumDeclaration2() instead')
  EnumDeclaration enumDeclaration(
      Comment? comment,
      List<Annotation>? metadata,
      Token enumKeyword,
      SimpleIdentifier name,
      Token leftBracket,
      List<EnumConstantDeclaration> constants,
      Token rightBracket);

  /// Returns a newly created enumeration declaration. Either or both of the
  /// [comment] and [metadata] can be `null` if the declaration does not have
  /// the corresponding attribute. The list of [constants] must contain at least
  /// one value.
  EnumDeclaration enumDeclaration2({
    required Comment? comment,
    required List<Annotation>? metadata,
    required Token enumKeyword,
    required SimpleIdentifier name,
    required TypeParameterList? typeParameters,
    required WithClause? withClause,
    required ImplementsClause? implementsClause,
    required Token leftBracket,
    required List<EnumConstantDeclaration> constants,
    required Token? semicolon,
    required List<ClassMember> members,
    required Token rightBracket,
  });

  /// Returns a newly created export directive. Either or both of the
  /// [comment] and [metadata] can be `null` if the directive does not have the
  /// corresponding attribute. The list of [combinators] can be `null` if there
  /// are no combinators.
  ExportDirective exportDirective(
      Comment? comment,
      List<Annotation>? metadata,
      Token keyword,
      StringLiteral libraryUri,
      List<Configuration>? configurations,
      List<Combinator>? combinators,
      Token semicolon);

  /// Returns a newly created function body consisting of an expression.
  /// The [keyword] can be `null` if the function body is not an async function
  /// body.
  @Deprecated("Use expressionFunctionBody2, with new 'star' parameter")
  ExpressionFunctionBody expressionFunctionBody(Token? keyword,
      Token functionDefinition, Expression expression, Token? semicolon);

  /// Returns a newly created function body consisting of an expression.
  /// The [keyword] can be `null` if the function body is not an async function
  /// body. The [star] can be `null` if there is no star following the keyword
  /// (and must be `null` if there is no keyword).
  ExpressionFunctionBody expressionFunctionBody2({
    Token? keyword,
    Token? star,
    required Token functionDefinition,
    required Expression expression,
    Token? semicolon,
  });

  /// Returns a newly created expression statement.
  ExpressionStatement expressionStatement(
      Expression expression, Token? semicolon);

  /// Returns a newly created extends clause.
  ExtendsClause extendsClause(Token extendsKeyword, NamedType superclass);

  /// Return a newly created extension declaration. The list of [typeParameters]
  /// can be `null` if there are no type parameters.
  ExtensionDeclaration extensionDeclaration(
      {Comment? comment,
      List<Annotation>? metadata,
      required Token extensionKeyword,
      Token? typeKeyword,
      SimpleIdentifier? name,
      TypeParameterList? typeParameters,
      required Token onKeyword,
      required TypeAnnotation extendedType,
      required Token leftBracket,
      required List<ClassMember> members,
      required Token rightBracket});

  /// Return a newly created extension override. The list of [typeArguments]
  /// can be `null` if there are no type arguments.
  ExtensionOverride extensionOverride(
      {required Identifier extensionName,
      TypeArgumentList? typeArguments,
      required ArgumentList argumentList});

  /// Returns a newly created field declaration. Either or both of the
  /// [comment] and [metadata] can be `null` if the declaration does not have
  /// the corresponding attribute. The [abstractKeyword], [augmentKeyword],
  /// [covariantKeyword], [externalKeyword] and [staticKeyword] can be `null` if
  /// the field does not have the corresponding modifier.
  FieldDeclaration fieldDeclaration2(
      {Comment? comment,
      List<Annotation>? metadata,
      Token? abstractKeyword,
      Token? augmentKeyword,
      Token? covariantKeyword,
      Token? externalKeyword,
      Token? staticKeyword,
      required VariableDeclarationList fieldList,
      required Token semicolon});

  /// Returns a newly created formal parameter. Either or both of the [comment]
  /// and [metadata] can be `null` if the parameter does not have the
  /// corresponding attribute. The [keyword] can be `null` if there is a type.
  /// The [type] must be `null` if the keyword is 'var'. The [thisKeyword] and
  /// [period] can be `null` if the keyword 'this' was not provided.  The
  /// [parameters] can be `null` if this is not a function-typed field formal
  /// parameter.
  FieldFormalParameter fieldFormalParameter2(
      {Comment? comment,
      List<Annotation>? metadata,
      Token? covariantKeyword,
      Token? requiredKeyword,
      Token? keyword,
      TypeAnnotation? type,
      required Token thisKeyword,
      required Token period,
      required SimpleIdentifier identifier,
      TypeParameterList? typeParameters,
      FormalParameterList? parameters,
      Token? question});

  /// Returns a newly created for each part that includes a declaration.
  ForEachPartsWithDeclaration forEachPartsWithDeclaration(
      {required DeclaredIdentifier loopVariable,
      required Token inKeyword,
      required Expression iterable});

  /// Returns a newly created for each part that includes an identifier that is
  /// declared outside of the loop.
  ForEachPartsWithIdentifier forEachPartsWithIdentifier(
      {required SimpleIdentifier identifier,
      required Token inKeyword,
      required Expression iterable});

  /// Returns a newly created for element that can be part of a list, map or set
  /// literal.
  ForElement forElement(
      {Token? awaitKeyword,
      required Token forKeyword,
      required Token leftParenthesis,
      required ForLoopParts forLoopParts,
      required Token rightParenthesis,
      required CollectionElement body});

  /// Returns a newly created parameter list. The list of [parameters] can be
  /// `null` if there are no parameters. The [leftDelimiter] and
  /// [rightDelimiter] can be `null` if there are no optional parameters.
  FormalParameterList formalParameterList(
      Token leftParenthesis,
      List<FormalParameter> parameters,
      Token? leftDelimiter,
      Token? rightDelimiter,
      Token rightParenthesis);

  /// Returns a newly created for part that includes a declaration.
  ForPartsWithDeclarations forPartsWithDeclarations(
      {required VariableDeclarationList variables,
      required Token leftSeparator,
      Expression? condition,
      required Token rightSeparator,
      List<Expression>? updaters});

  /// Returns a newly created for part that includes an expression.
  ForPartsWithExpression forPartsWithExpression(
      {Expression? initialization,
      required Token leftSeparator,
      Expression? condition,
      required Token rightSeparator,
      List<Expression>? updaters});

  /// Returns a newly created for statement.
  ForStatement forStatement(
      {Token? awaitKeyword,
      required Token forKeyword,
      required Token leftParenthesis,
      required ForLoopParts forLoopParts,
      required Token rightParenthesis,
      required Statement body});

  /// Returns a newly created function declaration. Either or both of the
  /// [comment] and [metadata] can be `null` if the function does not have the
  /// corresponding attribute. The [augmentKeyword] can be `null` if the
  /// function is not a function augmentation. The [externalKeyword] can be
  /// `null` if the function is not an external function. The [returnType] can
  /// be `null` if no return type was specified. The [propertyKeyword] can be
  /// `null` if the function is neither a getter or a setter.
  FunctionDeclaration functionDeclaration(
      Comment? comment,
      List<Annotation>? metadata,
      Token? augmentKeyword,
      Token? externalKeyword,
      TypeAnnotation? returnType,
      Token? propertyKeyword,
      SimpleIdentifier name,
      FunctionExpression functionExpression);

  /// Returns a newly created function declaration statement.
  FunctionDeclarationStatement functionDeclarationStatement(
      FunctionDeclaration functionDeclaration);

  /// Returns a newly created function declaration.
  FunctionExpression functionExpression(TypeParameterList? typeParameters,
      FormalParameterList? parameters, FunctionBody body);

  /// Returns a newly created function expression invocation.
  FunctionExpressionInvocation functionExpressionInvocation(Expression function,
      TypeArgumentList? typeArguments, ArgumentList argumentList);

  /// Returns a newly created function reference.  The [typeArguments] can be
  /// `null` if there are no type arguments being applied to the function.
  FunctionReference functionReference(
      {required Expression function, TypeArgumentList? typeArguments});

  /// Returns a newly created function type alias. Either or both of the
  /// [comment] and [metadata] can be `null` if the function does not have the
  /// corresponding attribute. The [returnType] can be `null` if no return type
  /// was specified. The [typeParameters] can be `null` if the function has no
  /// type parameters.
  FunctionTypeAlias functionTypeAlias(
      Comment? comment,
      List<Annotation>? metadata,
      Token keyword,
      TypeAnnotation? returnType,
      SimpleIdentifier name,
      TypeParameterList? typeParameters,
      FormalParameterList parameters,
      Token semicolon);

  /// Returns a newly created formal parameter. Either or both of the
  /// [comment] and [metadata] can be `null` if the parameter does not have the
  /// corresponding attribute. The [returnType] can be `null` if no return type
  /// was specified.
  FunctionTypedFormalParameter functionTypedFormalParameter2(
      {Comment? comment,
      List<Annotation>? metadata,
      Token? covariantKeyword,
      Token? requiredKeyword,
      TypeAnnotation? returnType,
      required SimpleIdentifier identifier,
      TypeParameterList? typeParameters,
      required FormalParameterList parameters,
      Token? question});

  /// Initialize a newly created generic function type.
  GenericFunctionType genericFunctionType(
      TypeAnnotation? returnType,
      Token functionKeyword,
      TypeParameterList? typeParameters,
      FormalParameterList parameters,
      {Token? question});

  /// Returns a newly created generic type alias. Either or both of the
  /// [comment] and [metadata] can be `null` if the variable list does not have
  /// the corresponding attribute. The [typeParameters] can be `null` if there
  /// are no type parameters.
  GenericTypeAlias genericTypeAlias(
      Comment? comment,
      List<Annotation>? metadata,
      Token typedefKeyword,
      SimpleIdentifier name,
      TypeParameterList? typeParameters,
      Token equals,
      TypeAnnotation type,
      Token semicolon);

  /// Returns a newly created hide clause.
  HideClause hideClause(
      {required Token hideKeyword,
      required List<ShowHideClauseElement> elements});

  /// Returns a newly created import show combinator.
  HideCombinator hideCombinator(
      Token keyword, List<SimpleIdentifier> hiddenNames);

  /// Returns a newly created if element that can be part of a list, map or set
  /// literal.
  IfElement ifElement(
      {required Token ifKeyword,
      required Token leftParenthesis,
      required Expression condition,
      required Token rightParenthesis,
      required CollectionElement thenElement,
      Token? elseKeyword,
      CollectionElement? elseElement});

  /// Returns a newly created if statement. The [elseKeyword] and
  /// [elseStatement] can be `null` if there is no else clause.
  IfStatement ifStatement(
      Token ifKeyword,
      Token leftParenthesis,
      Expression condition,
      Token rightParenthesis,
      Statement thenStatement,
      Token? elseKeyword,
      Statement? elseStatement);

  /// Returns a newly created implements clause.
  ImplementsClause implementsClause(
      Token implementsKeyword, List<NamedType> interfaces);

  /// Returns a newly created implicit call reference.
  ///
  /// The [typeArguments] can be `null` if there are no type arguments being
  /// applied to the reference.
  ImplicitCallReference implicitCallReference({
    required Expression expression,
    required MethodElement staticElement,
    required TypeArgumentList? typeArguments,
    required List<DartType> typeArgumentTypes,
  });

  /// Returns a newly created import directive. Either or both of the [comment]
  /// and [metadata] can be `null` if the function does not have the
  /// corresponding attribute. The [deferredKeyword] can be `null` if the import
  /// is not deferred. The [asKeyword] and [prefix] can be `null` if the import
  /// does not specify a prefix. The list of [combinators] can be `null` if
  /// there are no combinators.
  ImportDirective importDirective(
      Comment? comment,
      List<Annotation>? metadata,
      Token keyword,
      StringLiteral libraryUri,
      List<Configuration>? configurations,
      Token? deferredKeyword,
      Token? asKeyword,
      SimpleIdentifier? prefix,
      List<Combinator>? combinators,
      Token semicolon);

  /// Returns a newly created index expression.
  IndexExpression indexExpressionForCascade2(
      {required Token period,
      Token? question,
      required Token leftBracket,
      required Expression index,
      required Token rightBracket});

  /// Returns a newly created index expression.
  IndexExpression indexExpressionForTarget2(
      {required Expression target,
      Token? question,
      required Token leftBracket,
      required Expression index,
      required Token rightBracket});

  /// Returns a newly created instance creation expression.
  InstanceCreationExpression instanceCreationExpression(Token? keyword,
      ConstructorName constructorName, ArgumentList argumentList,
      {TypeArgumentList? typeArguments});

  /// Returns a newly created integer literal.
  IntegerLiteral integerLiteral(Token literal, int? value);

  /// Returns a newly created interpolation expression.
  InterpolationExpression interpolationExpression(
      Token leftBracket, Expression expression, Token? rightBracket);

  /// Returns a newly created string of characters that are part of a string
  /// interpolation.
  InterpolationString interpolationString(Token contents, String value);

  /// Returns a newly created is expression. The [notOperator] can be `null`
  /// if the sense of the test is not negated.
  IsExpression isExpression(Expression expression, Token isOperator,
      Token? notOperator, TypeAnnotation type);

  /// Returns a newly created label.
  Label label(SimpleIdentifier label, Token colon);

  /// Returns a newly created labeled statement.
  LabeledStatement labeledStatement(List<Label> labels, Statement statement);

  /// Returns a newly created library directive. Either or both of the
  /// [comment] and [metadata] can be `null` if the directive does not have the
  /// corresponding attribute.
  LibraryDirective libraryDirective(
      Comment? comment,
      List<Annotation>? metadata,
      Token libraryKeyword,
      LibraryIdentifier name,
      Token semicolon);

  /// Returns a newly created prefixed identifier.
  LibraryIdentifier libraryIdentifier(List<SimpleIdentifier> components);

  /// Returns a newly created list literal. The [constKeyword] can be `null`
  /// if the literal is not a constant. The [typeArguments] can be `null` if no
  /// type arguments were declared. The list of [elements] can be `null` if the
  /// list is empty.
  ListLiteral listLiteral(Token? constKeyword, TypeArgumentList? typeArguments,
      Token leftBracket, List<CollectionElement> elements, Token rightBracket);

  /// Returns a newly created map literal entry.
  MapLiteralEntry mapLiteralEntry(
      Expression key, Token separator, Expression value);

  /// Returns a newly created method declaration. Either or both of the
  /// [comment] and [metadata] can be `null` if the declaration does not have
  /// the corresponding attribute. The [externalKeyword] can be `null` if the
  /// method is not external. The [modifierKeyword] can be `null` if the method
  /// is neither abstract nor static. The [returnType] can be `null` if no
  /// return type was specified. The [propertyKeyword] can be `null` if the
  /// method is neither a getter or a setter. The [operatorKeyword] can be
  /// `null` if the method does not implement an operator. The [parameters] must
  /// be `null` if this method declares a getter.
  MethodDeclaration methodDeclaration(
      Comment? comment,
      List<Annotation>? metadata,
      Token? externalKeyword,
      Token? modifierKeyword,
      TypeAnnotation? returnType,
      Token? propertyKeyword,
      Token? operatorKeyword,
      SimpleIdentifier name,
      TypeParameterList? typeParameters,
      FormalParameterList? parameters,
      FunctionBody body);

  /// Returns a newly created method invocation. The [target] and [operator]
  /// can be `null` if there is no target.
  MethodInvocation methodInvocation(
      Expression? target,
      Token? operator,
      SimpleIdentifier methodName,
      TypeArgumentList? typeArguments,
      ArgumentList argumentList);

  /// Return a newly created mixin declaration.
  MixinDeclaration mixinDeclaration(
      Comment? comment,
      List<Annotation>? metadata,
      Token? augmentKeyword,
      Token mixinKeyword,
      SimpleIdentifier name,
      TypeParameterList? typeParameters,
      OnClause? onClause,
      ImplementsClause? implementsClause,
      Token leftBracket,
      List<ClassMember> members,
      Token rightBracket);

  /// Returns a newly created named expression.
  NamedExpression namedExpression(Label name, Expression expression);

  /// Returns a newly created named type. The [typeArguments] can be `null` if
  /// there are no type arguments. The [question] can be `null` if there is no
  /// question mark.
  NamedType namedType({
    required Identifier name,
    TypeArgumentList? typeArguments,
    Token? question,
  });

  /// Returns a newly created native clause.
  NativeClause nativeClause(Token nativeKeyword, StringLiteral? name);

  /// Returns a newly created function body consisting of the 'native' token,
  /// a string literal, and a semicolon.
  NativeFunctionBody nativeFunctionBody(
      Token nativeKeyword, StringLiteral? stringLiteral, Token semicolon);

  /// Returns a newly created list of nodes such that all of the nodes that
  /// are added to the list will have their parent set to the given [owner].
  NodeList<E> nodeList<E extends AstNode>(AstNode owner);

  /// Returns a newly created null literal.
  NullLiteral nullLiteral(Token literal);

  /// Return a newly created on clause.
  OnClause onClause(Token onKeyword, List<NamedType> superclassConstraints);

  /// Returns a newly created parenthesized expression.
  ParenthesizedExpression parenthesizedExpression(
      Token leftParenthesis, Expression expression, Token rightParenthesis);

  /// Returns a newly created part directive. Either or both of the [comment]
  /// and [metadata] can be `null` if the directive does not have the
  /// corresponding attribute.
  PartDirective partDirective(Comment? comment, List<Annotation>? metadata,
      Token partKeyword, StringLiteral partUri, Token semicolon);

  /// Returns a newly created part-of directive. Either or both of the
  /// [comment] and [metadata] can be `null` if the directive does not have the
  /// corresponding attribute.
  PartOfDirective partOfDirective(
      Comment? comment,
      List<Annotation>? metadata,
      Token partKeyword,
      Token ofKeyword,
      StringLiteral? uri,
      LibraryIdentifier? libraryName,
      Token semicolon);

  /// Returns a newly created postfix expression.
  PostfixExpression postfixExpression(Expression operand, Token operator);

  /// Returns a newly created prefixed identifier.
  PrefixedIdentifier prefixedIdentifier(
      SimpleIdentifier prefix, Token period, SimpleIdentifier identifier);

  /// Returns a newly created prefix expression.
  PrefixExpression prefixExpression(Token operator, Expression operand);

  /// Returns a newly created property access expression.
  PropertyAccess propertyAccess(
      Expression? target, Token operator, SimpleIdentifier propertyName);

  /// Returns a newly created redirecting invocation to invoke the constructor
  /// with the given name with the given arguments. The [constructorName] can be
  /// `null` if the constructor being invoked is the unnamed constructor.
  RedirectingConstructorInvocation redirectingConstructorInvocation(
      Token thisKeyword,
      Token? period,
      SimpleIdentifier? constructorName,
      ArgumentList argumentList);

  /// Returns a newly created rethrow expression.
  RethrowExpression rethrowExpression(Token rethrowKeyword);

  /// Returns a newly created return statement. The [expression] can be `null`
  /// if no explicit value was provided.
  ReturnStatement returnStatement(
      Token returnKeyword, Expression? expression, Token semicolon);

  /// Returns a newly created script tag.
  ScriptTag scriptTag(Token scriptTag);

  /// Returns a newly created set or map literal. The [constKeyword] can be
  /// `null` if the literal is not a constant. The [typeArguments] can be `null`
  /// if no type arguments were declared. The list of [elements] can be `null`
  /// if the set or map is empty.
  SetOrMapLiteral setOrMapLiteral(
      {Token? constKeyword,
      TypeArgumentList? typeArguments,
      required Token leftBracket,
      required List<CollectionElement> elements,
      required Token rightBracket});

  /// Returns a newly created show clause.
  ShowClause showClause(
      {required Token showKeyword,
      required List<ShowHideClauseElement> elements});

  /// Returns a newly created import show combinator.
  ShowCombinator showCombinator(
      Token keyword, List<SimpleIdentifier> shownNames);

  /// Returns a newly created element of a show or hide clause.
  ShowHideElement showHideElement(
      {required Token? modifier, required SimpleIdentifier name});

  /// Returns a newly created formal parameter. Either or both of the
  /// [comment] and [metadata] can be `null` if the parameter does not have the
  /// corresponding attribute. The [keyword] can be `null` if a type was
  /// specified. The [type] must be `null` if the keyword is 'var'.
  SimpleFormalParameter simpleFormalParameter2(
      {Comment? comment,
      List<Annotation>? metadata,
      Token? covariantKeyword,
      Token? requiredKeyword,
      Token? keyword,
      TypeAnnotation? type,
      required SimpleIdentifier? identifier});

  /// Returns a newly created identifier.
  SimpleIdentifier simpleIdentifier(Token token, {bool isDeclaration = false});

  /// Returns a newly created simple string literal.
  SimpleStringLiteral simpleStringLiteral(Token literal, String value);

  /// Returns a newly created spread element.
  SpreadElement spreadElement(
      {required Token spreadOperator, required Expression expression});

  /// Returns a newly created string interpolation expression.
  StringInterpolation stringInterpolation(List<InterpolationElement> elements);

  /// Returns a newly created super invocation to invoke the inherited
  /// constructor with the given name with the given arguments. The [period] and
  /// [constructorName] can be `null` if the constructor being invoked is the
  /// unnamed constructor.
  SuperConstructorInvocation superConstructorInvocation(
      Token superKeyword,
      Token? period,
      SimpleIdentifier? constructorName,
      ArgumentList argumentList);

  /// Returns a newly created super expression.
  SuperExpression superExpression(Token superKeyword);

  /// Returns a newly created super-initializer parameter. Either or both of
  /// the [comment] and [metadata] can be `null` if the parameter does not have
  /// the corresponding attribute. The [keyword] can be `null` if there is a
  /// type. The [type] must be `null` if the keyword is 'var'. The [parameters]
  /// can be `null` if this is not a function-typed super-initializer
  /// parameter.
  SuperFormalParameter superFormalParameter(
      {Comment? comment,
      List<Annotation>? metadata,
      Token? covariantKeyword,
      Token? requiredKeyword,
      Token? keyword,
      TypeAnnotation? type,
      required Token superKeyword,
      required Token period,
      required SimpleIdentifier identifier,
      TypeParameterList? typeParameters,
      FormalParameterList? parameters,
      Token? question});

  /// Returns a newly created switch case. The list of [labels] can be `null`
  /// if there are no labels.
  SwitchCase switchCase(List<Label> labels, Token keyword,
      Expression expression, Token colon, List<Statement> statements);

  /// Returns a newly created switch default. The list of [labels] can be
  /// `null` if there are no labels.
  SwitchDefault switchDefault(List<Label> labels, Token keyword, Token colon,
      List<Statement> statements);

  /// Returns a newly created switch statement. The list of [members] can be
  /// `null` if there are no switch members.
  SwitchStatement switchStatement(
      Token switchKeyword,
      Token leftParenthesis,
      Expression expression,
      Token rightParenthesis,
      Token leftBracket,
      List<SwitchMember> members,
      Token rightBracket);

  /// Returns a newly created symbol literal.
  SymbolLiteral symbolLiteral(Token poundSign, List<Token> components);

  /// Returns a newly created this expression.
  ThisExpression thisExpression(Token thisKeyword);

  /// Returns a newly created throw expression.
  ThrowExpression throwExpression(Token throwKeyword, Expression expression);

  /// Returns a newly created top-level variable declaration. Either or both
  /// of the [comment] and [metadata] can be `null` if the variable does not
  /// have the corresponding attribute.
  TopLevelVariableDeclaration topLevelVariableDeclaration(
      Comment? comment,
      List<Annotation>? metadata,
      VariableDeclarationList variableList,
      Token semicolon,
      {Token? externalKeyword});

  /// Returns a newly created try statement. The list of [catchClauses] can be
  /// `null` if there are no catch clauses. The [finallyKeyword] and
  /// [finallyBlock] can be `null` if there is no finally clause.
  TryStatement tryStatement(
      Token tryKeyword,
      Block body,
      List<CatchClause> catchClauses,
      Token? finallyKeyword,
      Block? finallyBlock);

  /// Returns a newly created list of type arguments.
  TypeArgumentList typeArgumentList(
      Token leftBracket, List<TypeAnnotation> arguments, Token rightBracket);

  /// Returns a newly created type literal.
  TypeLiteral typeLiteral({required NamedType typeName});

  /// Returns a newly created type parameter. Either or both of the [comment]
  /// and [metadata] can be `null` if the parameter does not have the
  /// corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
  /// the parameter does not have an upper bound.
  TypeParameter typeParameter(Comment? comment, List<Annotation>? metadata,
      SimpleIdentifier name, Token? extendsKeyword, TypeAnnotation? bound);

  /// Returns a newly created list of type parameters.
  TypeParameterList typeParameterList(Token leftBracket,
      List<TypeParameter> typeParameters, Token rightBracket);

  /// Returns a newly created variable declaration. The [equals] and
  /// [initializer] can be `null` if there is no initializer.
  VariableDeclaration variableDeclaration(
      SimpleIdentifier name, Token? equals, Expression? initializer);

  /// Returns a newly created variable declaration list. Either or both of the
  /// [comment] and [metadata] can be `null` if the variable list does not have
  /// the corresponding attribute. The [keyword] can be `null` if a type was
  /// specified. The [type] must be `null` if the keyword is 'var'.
  ///
  /// Use [variableDeclarationList2] instead.
  VariableDeclarationList variableDeclarationList(
      Comment? comment,
      List<Annotation>? metadata,
      Token? keyword,
      TypeAnnotation? type,
      List<VariableDeclaration> variables);

  /// Returns a newly created variable declaration list. Either or both of the
  /// [comment] and [metadata] can be `null` if the variable list does not have
  /// the corresponding attribute. The [keyword] can be `null` if a type was
  /// specified. The [type] must be `null` if the keyword is 'var'.
  VariableDeclarationList variableDeclarationList2(
      {Comment? comment,
      List<Annotation>? metadata,
      Token? lateKeyword,
      Token? keyword,
      TypeAnnotation? type,
      required List<VariableDeclaration> variables});

  /// Returns a newly created variable declaration statement.
  VariableDeclarationStatement variableDeclarationStatement(
      VariableDeclarationList variableList, Token semicolon);

  /// Returns a newly created while statement.
  WhileStatement whileStatement(Token whileKeyword, Token leftParenthesis,
      Expression condition, Token rightParenthesis, Statement body);

  /// Returns a newly created with clause.
  WithClause withClause(Token withKeyword, List<NamedType> mixinTypes);

  /// Returns a newly created yield expression. The [star] can be `null` if no
  /// star was provided.
  YieldStatement yieldStatement(
      Token yieldKeyword, Token? star, Expression expression, Token semicolon);
}
