// 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:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:front_end/src/scanner/token.dart';
import 'package:meta/meta.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.
   */
  Annotation annotation(Token atSign, Identifier name, 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 [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 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 [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,
      TypeName superclass,
      WithClause withClause,
      ImplementsClause implementsClause,
      Token semicolon);

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

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

  /**
   * 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, Identifier identifier);

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

  /**
   * 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. The [body] can be `null` if
   * the constructor does not have a body.
   */
  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(
      TypeName type, Token period, SimpleIdentifier name);

  /**
   * 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.
   */
  EnumDeclaration enumDeclaration(
      Comment comment,
      List<Annotation> metadata,
      Token enumKeyword,
      SimpleIdentifier name,
      Token leftBracket,
      List<EnumConstantDeclaration> constants,
      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 a block of
   * statements. The [keyword] can be `null` if the function body is not an
   * async function body.
   */
  ExpressionFunctionBody expressionFunctionBody(Token keyword,
      Token functionDefinition, 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, TypeName superclass);

  /**
   * 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 [staticKeyword] can be `null` if the field is
   * not a static field.
   *
   * Use [fieldDeclaration2] instead.
   */
  @deprecated
  FieldDeclaration fieldDeclaration(Comment comment, List<Annotation> metadata,
      Token staticKeyword, VariableDeclarationList fieldList, Token semicolon);

  /**
   * 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 [staticKeyword] can be `null` if the field is
   * not a static field.
   */
  FieldDeclaration fieldDeclaration2(
      {Comment comment,
      List<Annotation> metadata,
      Token covariantKeyword,
      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.
   *
   * Use [fieldFormalParameter2] instead.
   */
  @deprecated
  FieldFormalParameter fieldFormalParameter(
      Comment comment,
      List<Annotation> metadata,
      Token keyword,
      TypeAnnotation type,
      Token thisKeyword,
      Token period,
      SimpleIdentifier identifier,
      TypeParameterList typeParameters,
      FormalParameterList parameters);

  /**
   * 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 keyword,
      TypeAnnotation type,
      @required Token thisKeyword,
      @required Token period,
      @required SimpleIdentifier identifier,
      TypeParameterList typeParameters,
      FormalParameterList parameters});

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

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

  /**
   * Returns a newly created for-each statement whose loop control variable
   * is declared internally (in the for-loop part). The [awaitKeyword] can be
   * `null` if this is not an asynchronous for loop.
   */
  ForEachStatement forEachStatementWithDeclaration(
      Token awaitKeyword,
      Token forKeyword,
      Token leftParenthesis,
      DeclaredIdentifier loopVariable,
      Token inKeyword,
      Expression iterator,
      Token rightParenthesis,
      Statement body);

  /**
   * Returns a newly created for-each statement whose loop control variable
   * is declared outside the for loop. The [awaitKeyword] can be `null` if this
   * is not an asynchronous for loop.
   */
  ForEachStatement forEachStatementWithReference(
      Token awaitKeyword,
      Token forKeyword,
      Token leftParenthesis,
      SimpleIdentifier identifier,
      Token inKeyword,
      Expression iterator,
      Token rightParenthesis,
      Statement 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(
      {VariableDeclarationList variables,
      Token leftSeparator,
      Expression condition,
      Token rightSeparator,
      List<Expression> updaters});

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

  /**
   * Returns a newly created for statement. Either the [variableList] or the
   * [initialization] must be `null`. Either the [condition] and the list of
   * [updaters] can be `null` if the loop does not have the corresponding
   * attribute.
   */
  ForStatement forStatement(
      Token forKeyword,
      Token leftParenthesis,
      VariableDeclarationList variableList,
      Expression initialization,
      Token leftSeparator,
      Expression condition,
      Token rightSeparator,
      List<Expression> updaters,
      Token rightParenthesis,
      Statement body);

  /**
   * Returns a newly created for statement.
   */
  ForStatement2 forStatement2(
      {Token forKeyword,
      Token leftParenthesis,
      ForLoopParts forLoopParts,
      Token rightParenthesis,
      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 [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 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 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.
   *
   * Use [functionTypedFormalParameter2] instead.
   */
  @deprecated
  FunctionTypedFormalParameter functionTypedFormalParameter(
      Comment comment,
      List<Annotation> metadata,
      TypeAnnotation returnType,
      SimpleIdentifier identifier,
      TypeParameterList typeParameters,
      FormalParameterList parameters);

  /**
   * 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,
      TypeAnnotation returnType,
      @required SimpleIdentifier identifier,
      TypeParameterList typeParameters,
      @required FormalParameterList parameters});

  /**
   * 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,
      GenericFunctionType functionType,
      Token semicolon);

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

  /**
   * 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<TypeName> interfaces);

  /**
   * 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 indexExpressionForCascade(
      Token period, Token leftBracket, Expression index, Token rightBracket);

  /**
   * Returns a newly created index expression.
   */
  IndexExpression indexExpressionForTarget(Expression target, Token leftBracket,
      Expression index, 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<Expression> elements, Token rightBracket);

  /**
   * Returns a newly created list literal.
   */
  ListLiteral2 listLiteral2(
      {Token constKeyword,
      TypeArgumentList typeArguments,
      Token leftBracket,
      List<CollectionElement> elements,
      Token rightBracket});

  /**
   * Returns a newly created for element that can be part of a map literal.
   */
  MapForElement mapForElement(
      {Token awaitKeyword,
      Token forKeyword,
      Token leftParenthesis,
      ForLoopParts forLoopParts,
      Token rightParenthesis,
      MapElement body});

  /**
   * Returns a newly created if element that can be part of a map literal.
   */
  MapIfElement mapIfElement(
      {Token ifKeyword,
      Token leftParenthesis,
      Expression condition,
      Token rightParenthesis,
      MapElement thenElement,
      Token elseKeyword,
      MapElement elseElement});

  /**
   * Returns a newly created 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 [entries] can be `null` if the map is empty.
   */
  MapLiteral mapLiteral(Token constKeyword, TypeArgumentList typeArguments,
      Token leftBracket, List<MapLiteralEntry> entries, Token rightBracket);

  /**
   * Returns a newly created map literal.
   */
  MapLiteral2 mapLiteral2(
      {Token constKeyword,
      TypeArgumentList typeArguments,
      Token leftBracket,
      List<MapElement> entries,
      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 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 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]. The
   * list will initially be populated with the given [elements].
   */
  NodeList<E> nodeList<E extends AstNode>(AstNode owner, [List<E> elements]);

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

  /**
   * Return a newly created on clause.
   */
  OnClause onClause(Token onKeyword, List<TypeName> 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 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 is empty.
   */
  SetLiteral setLiteral(Token constKeyword, TypeArgumentList typeArguments,
      Token leftBracket, List<Expression> elements, Token rightBracket);

  /**
   * Returns a newly created set literal.
   */
  SetLiteral2 setLiteral2(
      {Token constKeyword,
      TypeArgumentList typeArguments,
      Token leftBracket,
      List<CollectionElement> elements,
      Token rightBracket});

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

  /**
   * 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'.
   *
   * Use [simpleFormalParameter2] instead.
   */
  @deprecated
  SimpleFormalParameter simpleFormalParameter(
      Comment comment,
      List<Annotation> metadata,
      Token keyword,
      TypeAnnotation type,
      SimpleIdentifier identifier);

  /**
   * 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 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({Token spreadOperator, 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 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);

  /**
   * 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 name. The [typeArguments] can be `null` if
   * there are no type arguments. The [question] can be `null` if there is no
   * question mark.
   */
  TypeName typeName(Identifier name, TypeArgumentList typeArguments,
      {Token question});

  /**
   * 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'.
   */
  VariableDeclarationList variableDeclarationList(
      Comment comment,
      List<Annotation> metadata,
      Token keyword,
      TypeAnnotation type,
      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<TypeName> 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);
}
