//===--- DeclSyntax.h - Declaration Syntax Interface ------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the interface for declaration-specific syntax nodes,
// such as for structures, enumerations, type aliases, and constants.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SYNTAX_DECLSYNTAX_H
#define SWIFT_SYNTAX_DECLSYNTAX_H

#include "swift/Syntax/References.h"
#include "swift/Syntax/RawSyntax.h"
#include "swift/Syntax/Syntax.h"
#include "swift/Syntax/SyntaxCollection.h"
#include "swift/Syntax/SyntaxData.h"
#include "swift/Syntax/TokenSyntax.h"
#include "swift/Syntax/TypeSyntax.h"
#include "swift/Syntax/UnknownSyntax.h"

#include "llvm/ADT/BitVector.h"

namespace swift {
namespace syntax {

class ExprSyntax;
class ExprSyntaxData;
class CodeBlockStmtSyntax;
class CodeBlockStmtSyntaxData;
class TypeAttributesSyntax;
class TypeAttributesSyntaxData;
class DeclModifierListSyntax;
class GenericWhereClauseSyntax;
class GenericWhereClauseSyntaxData;
class GenericParameterListSyntax;
class GenericParameterListSyntaxData;

#pragma mark declaration-modifier Data

class DeclModifierSyntaxData final : public SyntaxData {
  friend struct SyntaxFactory;
  friend class SyntaxData;
  friend class Syntax;
  friend class DeclModifierSyntax;

  DeclModifierSyntaxData(const RC<RawSyntax> Raw,
                         const SyntaxData *Parent = nullptr,
                         const CursorIndex IndexInParent = 0);

  static RC<DeclModifierSyntaxData> make(const RC<RawSyntax> Raw,
                                         const SyntaxData *Parent = nullptr,
                                         const CursorIndex IndexInParent = 0);

  static RC<DeclModifierSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *SD) {
    return SD->getKind() == SyntaxKind::DeclModifier;
  }
};

#pragma mark declaration-modifier API

/// declaration-modifier -> access-level-modifier
///                       | mutation-modifier
///                       | 'class'
///                       | 'convenience'
///                       | 'dynamic'
///                       | 'final'
///                       | 'infix'
///                       | 'lazy'
///                       | 'optional'
///                       | 'override'
///                       | 'postfix'
///                       | 'prefix'
///                       | 'required'
///                       | 'static'
///                       | 'unowned'
///                       | 'unowned(safe)'
///                       | 'unowned(unsafe)'
///                       | 'weak'
/// access-level-modifier -> 'private' | 'private' '(' 'set' ')'
///                        | 'fileprivate' | 'fileprivate' '(' 'set' ')'
///                        | 'internal' | 'internal' '(' 'set' ')'
///                        | 'public' | 'public' '(' 'set' ')'
///                        | 'open' | 'open' '(' 'set' ')'
/// mutation-modifier -> 'mutating' | 'nonmutating'
class DeclModifierSyntax final : public Syntax {
  friend struct SyntaxFactory;
  friend class Syntax;
  friend class SyntaxData;
  friend class DeclModifierSyntaxData;

  enum class Cursor : CursorIndex {
    Name,
    LeftParen,
    Argument,
    RightParen
  };

  DeclModifierSyntax(const RC<SyntaxData> Root, const DataType *Data)
    : Syntax(Root, Data) {}

public:
  using DataType = DeclModifierSyntaxData;

  /// Return the name of the modifier.
  RC<TokenSyntax> getName() const;

  /// Return a DeclModifierSyntax with the given name.
  DeclModifierSyntax withName(RC<TokenSyntax> NewName) const;

  /// Return the left parenthesis '(' token as a part of the argument clause,
  /// if there is one.
  RC<TokenSyntax> getLeftParenToken() const;

  /// Return a DeclModifierSyntax with the given left parenthesis '(' token.
  DeclModifierSyntax withLeftParenToken(RC<TokenSyntax> NewLeftParen) const;

  /// Get the argument to the declaration modifier.
  ///
  /// This is either:
  /// - 'set' for the access modifiers such as 'private' or 'public', or
  /// - 'safe' / 'unsafe' for the 'unowned' modifier.
  RC<TokenSyntax> getArgument() const;

  /// Return a DeclModifierSyntax with the given argument.
  DeclModifierSyntax withArgument(RC<TokenSyntax> NewArgument) const;

  /// Return the right parenthesis ')' token as a part of the argument clause,
  /// if there is one.
  RC<TokenSyntax> getRightParenToken() const;

  /// Return a DeclModifierSyntax with the given right parenthesis ')' token.
  DeclModifierSyntax withRightParenToken(RC<TokenSyntax> NewRightParen) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::DeclModifier;
  }
};

#pragma mark declaration-modifiers Data

using DeclModifierListSyntaxData =
  SyntaxCollectionData<SyntaxKind::DeclModifierList, DeclModifierSyntax>;

#pragma mark declaration-modifiers API

class DeclModifierListSyntax final :
  public SyntaxCollection<SyntaxKind::DeclModifierList, DeclModifierSyntax> {

  friend struct SyntaxFactory;
  friend class Syntax;
  friend class SyntaxData;
  friend class FunctionDeclSyntax;

  using DataType = DeclModifierListSyntaxData;

  DeclModifierListSyntax(const RC<SyntaxData> Root, const DataType *Data)
    : SyntaxCollection(Root, Data) {}

public:
  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::DeclModifierList;
  }
};

#pragma mark declaration Data

class DeclSyntaxData : public SyntaxData {
protected:
  DeclSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
                 CursorIndex IndexInParent = 0);

public:
  static bool classof(const SyntaxData *S) { return S->isDecl(); }
};

#pragma mark declaration API

class DeclSyntax : public Syntax {
  friend class Syntax;
  using DataType = DeclSyntaxData;
protected:
  DeclSyntax(const RC<SyntaxData> Root, const DeclSyntaxData *Data);

public:
  static bool classof(const SyntaxData *S) { return S->isDecl(); }
};

#pragma mark - unknown-declaration Data

class UnknownDeclSyntaxData : public UnknownSyntaxData {
  UnknownDeclSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
                        CursorIndex IndexInParent = 0);
public:
  static RC<UnknownDeclSyntaxData> make(RC<RawSyntax> Raw,
                                        const SyntaxData *Parent = nullptr,
                                        CursorIndex IndexInParent = 0);

  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::UnknownDecl;
  }
};

#pragma mark - unknown-declaration API

class UnknownDeclSyntax : public UnknownSyntax {
  friend class SyntaxData;
  friend class UnknownStmtSyntaxData;
  friend class LegacyASTTransformer;

  using DataType = UnknownDeclSyntaxData;

  UnknownDeclSyntax(const RC<SyntaxData> Root,
                    const UnknownDeclSyntaxData *Data);

public:
  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::UnknownDecl;
  }
};

#pragma mark declaration-members Data

class DeclMembersSyntaxData final : public SyntaxData {
  friend class SyntaxData;
  friend class DeclMembersSyntaxBuilder;
  friend struct SyntaxFactory;

  DeclMembersSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
                        CursorIndex IndexInParent = 0);

public:
  static RC<DeclMembersSyntaxData> make(RC<RawSyntax> Raw,
                                        const SyntaxData *Parent = nullptr,
                                        CursorIndex IndexInParent = 0);
  static RC<DeclMembersSyntaxData> makeBlank();

  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::DeclMembers;
  }
};

#pragma mark -
#pragma mark declaration-members API

class DeclMembersSyntax final : public Syntax {
  using DataType = DeclMembersSyntaxData;
  friend struct SyntaxFactory;
  friend class SyntaxData;
  friend class Syntax;
  friend class DeclMembersSyntaxBuilder;
  friend class StructDeclSyntax;

  DeclMembersSyntax(RC<SyntaxData> Root,
                    const DeclMembersSyntaxData *Data);
public:
  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::DeclMembers;
  }
};

#pragma mark -
#pragma mark declaration-members Builder (TODO)

class DeclMembersSyntaxBuilder final {
  RawSyntax::LayoutList MembersLayout;
public:
  DeclMembersSyntaxBuilder &addMember(DeclSyntax Member);
  DeclMembersSyntax build() const;
};

#pragma mark -
#pragma mark struct-declaration Data

class StructDeclSyntaxData final : public DeclSyntaxData {
  friend class SyntaxData;
  friend class StructDeclSyntax;
  friend class StructDeclSyntaxBuilder;
  friend struct SyntaxFactory;

  RC<GenericWhereClauseSyntaxData> CachedWhereClause;
  RC<GenericParameterClauseSyntaxData> CachedGenericParams;
  RC<DeclMembersSyntaxData> CachedMembers;

  StructDeclSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
                       CursorIndex IndexInParent = 0);

  static RC<StructDeclSyntaxData> make(RC<RawSyntax> Raw,
                                       const SyntaxData *Parent = nullptr,
                                       CursorIndex IndexInParent = 0);
  static RC<StructDeclSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::StructDecl;
  }
};

#pragma mark - struct-declaration API

/// struct-declaration -> attributes? access-level-modifier?
///                       'struct' struct-name
///                       generic-parameter-clause? type-inheritance-clause?
///                       generic-where-clause?
///                       '{' struct-members '}'
/// struct-name -> identifier
/// struct-members -> struct-member struct-members?
/// struct-member -> declaration | compiler-control-statement
class StructDeclSyntax final : public DeclSyntax {
  using DataType = StructDeclSyntaxData;
  friend struct SyntaxFactory;
  friend class Syntax;
  friend class SyntaxData;
  friend class StructDeclSyntaxData;
  friend class StructDeclSyntaxBuilder;

  enum class Cursor : CursorIndex {
    StructKeyword,
    Identifier,
    GenericParameterClause,
    GenericWhereClause,
    LeftBrace,
    Members,
    RightBrace,
    First = StructKeyword,
    Last = RightBrace,
  };

  StructDeclSyntax(const RC<SyntaxData> Root, const StructDeclSyntaxData *Data);

  const StructDeclSyntaxData *getData() const {
    return cast<StructDeclSyntaxData>(Data);
  }

public:
  /// Return the 'struct' keyword attached to the declaration.
  RC<TokenSyntax> getStructKeyword() const;

  /// Return a StructDeclSyntax with the given 'struct' keyword.
  StructDeclSyntax withStructKeyword(RC<TokenSyntax> NewStructKeyword) const;

  /// Return the identifier of the struct.
  RC<TokenSyntax> getIdentifier() const;

  /// Return a StructDeclSyntax with the given identifier.
  StructDeclSyntax withIdentifier(RC<TokenSyntax> NewIdentifier) const;

  /// Return the generic parameter clause of the struct declaration.
  GenericParameterClauseSyntax getGenericParameterClause() const;

  /// Return a StructDeclSyntax with the given generic parameter clause.
  StructDeclSyntax
  withGenericParameterClause(GenericParameterClauseSyntax NewGenericParams)
  const;

  /// Return the where clause of the struct declaration.
  GenericWhereClauseSyntax getGenericWhereClause() const;

  /// Return a StructDeclSyntax with the given generic where clause.
  StructDeclSyntax
  withWhereClause(GenericWhereClauseSyntax NewWhereClause) const;

  /// Return the left brace '{' token of the struct declaration.
  RC<TokenSyntax> getLeftBraceToken() const;

  /// Return a StructDeclSyntax with the given left brace '{' token.
  StructDeclSyntax withLeftBrace(RC<TokenSyntax> NewLeftBrace) const;

  /// Return the members' syntax of the struct.
  DeclMembersSyntax getMembers() const;

  /// Return a StructDeclSyntax with the given new members.
  StructDeclSyntax withMembers(DeclMembersSyntax NewMembers) const;

  /// Return the right brace '}' token of the struct declaration.
  RC<TokenSyntax> getRightBraceToken() const;

  /// Return a StructDeclSyntax with the given right brace '}' token.
  StructDeclSyntax withRightBrace(RC<TokenSyntax> NewRightBrace) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::StructDecl;
  }
};

#pragma mark - struct-declaration Builder

class StructDeclSyntaxBuilder final {
  RawSyntax::LayoutList StructLayout;
public:
  StructDeclSyntaxBuilder();
  StructDeclSyntaxBuilder &useStructKeyword(RC<TokenSyntax> StructKeyword);
  StructDeclSyntaxBuilder &useIdentifier(RC<TokenSyntax> Identifier);
  StructDeclSyntaxBuilder &useLeftBrace(RC<TokenSyntax> LeftBrace);

  StructDeclSyntaxBuilder &
  useGenericParameterClause(GenericParameterClauseSyntax GenericParams);

  StructDeclSyntaxBuilder &
  useGenericWhereClause(GenericWhereClauseSyntax GenericWhereClause);

  StructDeclSyntaxBuilder &useMembers(DeclMembersSyntax Members);
  StructDeclSyntaxBuilder &useRightBrace(RC<TokenSyntax> RightBrace);
  StructDeclSyntax build() const;
};

#pragma mark -
#pragma mark - type-alias Data

class TypeAliasDeclSyntaxData final : public DeclSyntaxData {
  friend class SyntaxData;
  friend struct SyntaxFactory;
  friend class TypeAliasDeclSyntaxBuilder;

  TypeAliasDeclSyntaxData(RC<RawSyntax> Raw,
                          const SyntaxData *Parent = nullptr,
                          CursorIndex IndexInParent = 0);
  static RC<TypeAliasDeclSyntaxData> make(RC<RawSyntax> Raw,
                                          const SyntaxData *Parent = nullptr,
                                          CursorIndex IndexInParent = 0);
  static RC<TypeAliasDeclSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::TypeAliasDecl;
  }
};

#pragma mark -
#pragma mark - type-alias API

class TypeAliasDeclSyntax final : public DeclSyntax {
  friend struct SyntaxFactory;
  friend class SyntaxData;
  friend class TypeAliasDeclSyntaxData;
  friend class TypeAliasDeclSyntaxBuilder;

  using DataType = TypeAliasDeclSyntaxData;

  enum Cursor : CursorIndex {
    TypeAliasKeyword,
    Identifier,
    GenericParameterClause,
    EqualToken,
    Type
  };

  TypeAliasDeclSyntax(RC<SyntaxData> Root, const TypeAliasDeclSyntaxData *Data);

public:
  /// Return the 'typealias' keyword for the declaration.
  RC<TokenSyntax> getTypealiasKeyword() const {
    return cast<TokenSyntax>(getRaw()->getChild(Cursor::TypeAliasKeyword));
  }

  /// Return a TypeAliasDeclSyntax with the given 'typealias' keyword.
  TypeAliasDeclSyntax
  withTypeAliasKeyword(RC<TokenSyntax> NewTypeAliasKeyword) const;

  /// Return the identifier for the declaration.
  RC<TokenSyntax> getIdentifier() const;

  /// Return a TypeAliasDeclSyntax with the given identifier.
  TypeAliasDeclSyntax withIdentifier(RC<TokenSyntax> NewIdentifier) const;

  /// Return the generic parameter clause of the declaration.
  GenericParameterClauseSyntax getGenericParameterClause() const;

  /// Return a TypeAliasDeclSyntax with the given generic parameter clause.
  TypeAliasDeclSyntax
  withGenericParameterClause( GenericParameterClauseSyntax NewGenericParams)
  const;

  /// Return the equal '=' token from the declaration.
  RC<TokenSyntax> getEqualToken() const;

  /// Return a TypeAliasDeclSyntax with the given equal '=' token.
  TypeAliasDeclSyntax
  withEqualToken(RC<TokenSyntax> NewEqualToken) const;

  /// Return the type syntax to which the type alias is assigned.
  TypeSyntax getTypeSyntax() const;

  /// Return a TypeAliasDeclSyntax with the given type assignment.
  TypeAliasDeclSyntax withTypeSyntax(TypeSyntax NewType) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::TypeAliasDecl;
  }
};

#pragma mark - type-alias Builder

class TypeAliasDeclSyntaxBuilder final {
  RawSyntax::LayoutList TypeAliasLayout;
public:
  TypeAliasDeclSyntaxBuilder();

  TypeAliasDeclSyntaxBuilder &
  useTypeAliasKeyword(RC<TokenSyntax> TypeAliasKeyword);

  TypeAliasDeclSyntaxBuilder &useIdentifier(RC<TokenSyntax> Identifier);

  TypeAliasDeclSyntaxBuilder &
  useGenericParameterClause(GenericParameterClauseSyntax GenericParams);

  TypeAliasDeclSyntaxBuilder &useEqualToken(RC<TokenSyntax> EqualToken);

  TypeAliasDeclSyntaxBuilder &useType(TypeSyntax ReferentType);

  TypeAliasDeclSyntax build() const;
};

#pragma mark - function-parameter Data

class FunctionParameterSyntaxData final : public SyntaxData {

  friend struct SyntaxFactory;
  friend class Syntax;
  friend class SyntaxData;
  friend class FunctionParameterSyntax;

  RC<TypeSyntaxData> CachedTypeSyntax;
  RC<ExprSyntaxData> CachedDefaultValue;

  FunctionParameterSyntaxData(RC<RawSyntax> Raw,
                              const SyntaxData *Parent = nullptr,
                              CursorIndex IndexInParent = 0);
  static RC<FunctionParameterSyntaxData>
  make(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
       CursorIndex IndexInParent = 0);
  static RC<FunctionParameterSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *SD) {
    return SD->getKind() == SyntaxKind::FunctionParameter;
  }
};

#pragma mark - function-parameter API

/// parameter ->
/// external-parameter-name? local-parameter-name ':'
///   type '...'? '='? expression? ','?
class FunctionParameterSyntax final : public Syntax {
  friend struct SyntaxFactory;
  friend class Syntax;
  friend class SyntaxData;
  friend class FunctionParameterSyntaxData;

  enum class Cursor : CursorIndex {
    ExternalName,
    LocalName,
    Colon,
    Type,
    Ellipsis,
    DefaultEqual,
    DefaultExpression,
    TrailingComma,
  };

public:
  using DataType = FunctionParameterSyntaxData;

  FunctionParameterSyntax(const RC<SyntaxData> Root, const DataType *Data)
    : Syntax(Root, Data) {}

  /// Get the external name of the parameter, if there is one.
  RC<TokenSyntax> getExternalName() const;

  /// Return a FunctionParameterSyntax with the given external name.
  FunctionParameterSyntax
  withExternalName(RC<TokenSyntax> NewExternalName) const;

  /// Return the local name of the parameter.
  RC<TokenSyntax> getLocalName() const;

  /// Return a FunctionParameterSyntax with the given local name.
  FunctionParameterSyntax
  withLocalName(RC<TokenSyntax> NewLocalName) const;

  /// Return the colon ':' token between the local name and type of the
  /// parameter.
  RC<TokenSyntax> getColonToken() const;

  /// Return a FunctionParameterSyntax with the given colon token between
  /// the local name and type.
  FunctionParameterSyntax
  withColonToken(RC<TokenSyntax> NewColonToken) const;

  /// Return the syntax for the type of this parameter.
  llvm::Optional<TypeSyntax> getTypeSyntax() const;

  /// Return a FunctionParameterSyntax with the given parameter type syntax.
  FunctionParameterSyntax
  withTypeSyntax(llvm::Optional<TypeSyntax> NewType) const;

  /// Return the equal '=' token in between the parameter type and the default
  /// value, if there is one.
  RC<TokenSyntax> getEqualToken() const;

  /// Return a FunctionParameterSyntax with the given equal '=' token in
  /// between the parameter type and the default value.
  FunctionParameterSyntax withEqualToken(RC<TokenSyntax> NewEqualToken) const;

  /// Return the expression for the default value of the parameter, if there
  /// is one.
  llvm::Optional<ExprSyntax> getDefaultValue() const;

  /// Return a FunctionParameterSyntax with the given default value. To remove
  /// the default value, pass llvm::None.
  FunctionParameterSyntax
  withDefaultValue(llvm::Optional<ExprSyntax> NewDefaultValue) const;

  /// Return the trailing comma on the parameter, if there is one.
  RC<TokenSyntax> getTrailingComma() const;

  /// Return a FunctionParameterSyntax with the given trailing comma.
  FunctionParameterSyntax
  withTrailingComma(RC<TokenSyntax> NewTrailingComma) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::FunctionParameter;
  }
};

#pragma mark - function-parameter-list API

/// parameter-list -> parameteter | parameter ',' parameter-list
class FunctionParameterListSyntax final : public
  SyntaxCollection<SyntaxKind::FunctionParameterList, FunctionParameterSyntax> {
  friend struct SyntaxFactory;
  friend class Syntax;
  friend class SyntaxData;
  friend class FunctionSignatureSyntax;

  using DataType = FunctionParameterListSyntaxData;

  FunctionParameterListSyntax(const RC<SyntaxData> Root,
                              const DataType *Data)
    : SyntaxCollection(Root, Data) {}

public:
  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::FunctionParameterList;
  }
};

#pragma mark - function-signature Data

class FunctionSignatureSyntaxData final : public SyntaxData {
  friend struct SyntaxFactory;
  friend class SyntaxData;
  friend class FunctionSignatureSyntax;

  RC<FunctionParameterListSyntaxData> CachedParameterList;
  RC<TypeAttributesSyntaxData> CachedReturnTypeAttributes;
  RC<TypeSyntaxData> CachedReturnTypeSyntax;

  FunctionSignatureSyntaxData(const RC<RawSyntax> Raw,
                              const SyntaxData *Parent = nullptr,
                              const CursorIndex IndexInParent = 0);

  static RC<FunctionSignatureSyntaxData>
  make(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
       CursorIndex IndexInParent = 0);
  static RC<FunctionSignatureSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *SD) {
    return SD->getKind() == SyntaxKind::FunctionSignature;
  }
};

#pragma mark - function-signature API

/// function-signature ->
///   '(' parameter-list? ')' (throws | rethrows)? '->' attributes? type
class FunctionSignatureSyntax final : public Syntax {
  friend struct SyntaxBuilder;
  friend class Syntax;
  friend class SyntaxData;
  friend class FunctionSignatureSyntaxData;

  enum class Cursor : CursorIndex {
    LeftParen,
    ParameterList,
    RightParen,
    ThrowsOrRethrows,
    Arrow,
    ReturnTypeAttributes,
    ReturnType,
  };

public:
  using DataType = FunctionSignatureSyntaxData;

  FunctionSignatureSyntax(const RC<SyntaxData> Root, const DataType *Data)
    : Syntax(Root, Data) {}

  /// Return the left parenthesis '(' token enclosing the parameter list.
  RC<TokenSyntax> getLeftParenToken() const;

  /// Return a FunctionSignatureSyntax with the given left parenthesis '(' token
  /// enclosing the parameter list.
  FunctionSignatureSyntax
  withLeftParenToken(RC<TokenSyntax> NewLeftParen) const;

  /// Return the parameter list for this signature.
  FunctionParameterListSyntax getParameterList() const;

  /// Return the parameter list for this signature.
  FunctionSignatureSyntax
  withParameterList(FunctionParameterListSyntax NewParameterList) const;

  /// Return the right parenthesis ')' token enclosing the parameter list.
  RC<TokenSyntax> getRightParenToken() const;

  /// Return a FunctionSignatureSyntax with the given right parenthesis ')' token
  /// enclosing the parameter list.
  FunctionSignatureSyntax
  withRightParenToken(RC<TokenSyntax> NewRightParen) const;

  /// Return the 'throws' token in this signature if it exists.
  RC<TokenSyntax> getThrowsToken() const;

  /// Return a FunctionSignatureSyntax with the given 'throws' token.
  FunctionSignatureSyntax withThrowsToken(RC<TokenSyntax> NewThrowsToken) const;

  /// Return the 'rethrows' token in this signature if it exists;
  RC<TokenSyntax> getRethrowsToken() const;

  /// Return a FunctionSignatureSyntax with the given 'rethrows' token.
  FunctionSignatureSyntax
  withRethrowsToken(RC<TokenSyntax> NewRethrowsToken) const;

  /// Return the arrow '->' token for the signature.
  RC<TokenSyntax> getArrowToken() const;

  /// Return a FunctionSignatureSyntax with the given arrow token
  FunctionSignatureSyntax withArrowToken(RC<TokenSyntax> NewArrowToken) const;

  /// Return the return type attributes for the signature.
  TypeAttributesSyntax getReturnTypeAttributes() const;

  /// Return a FunctionSignatureSyntax with the given return type attributes.
  FunctionSignatureSyntax
  withReturnTypeAttributes(TypeAttributesSyntax NewReturnTypeAttributes) const;

  /// Return the syntax for the return type of the signature.
  TypeSyntax getReturnTypeSyntax() const;

  /// Return a FunctionSignatureSyntax with the given return type.
  FunctionSignatureSyntax withReturnTypeSyntax(TypeSyntax NewReturnType) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::FunctionSignature;
  }
};

#pragma mark - function-declaration Data

class FunctionDeclSyntaxData final : public SyntaxData {
  friend struct SyntaxFactory;
  friend class SyntaxData;
  friend class FunctionDeclSyntax;

  RC<TypeAttributesSyntaxData> CachedAttributes;
  RC<DeclModifierListSyntaxData> CachedModifiers;
  RC<GenericParameterClauseSyntaxData> CachedGenericParams;
  RC<FunctionSignatureSyntaxData> CachedSignature;
  RC<GenericWhereClauseSyntaxData> CachedGenericWhereClause;
  RC<CodeBlockStmtSyntaxData> CachedBody;

  FunctionDeclSyntaxData(const RC<RawSyntax> Raw,
                         const SyntaxData *Parent = nullptr,
                         const CursorIndex IndexInParent = 0);

  static RC<FunctionDeclSyntaxData> make(const RC<RawSyntax> Raw,
                                         const SyntaxData *Parent = nullptr,
                                         const CursorIndex IndexInParent = 0);
  static RC<FunctionDeclSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *SD) {
    return SD->getKind() == SyntaxKind::FunctionDecl;
  }
};

#pragma mark - function-declaration API

class FunctionDeclSyntax final : public Syntax {
  friend struct SyntaxFactory;
  friend class Syntax;
  friend class SyntaxData;
  friend class FunctionDeclSyntaxData;

  enum class Cursor : CursorIndex {
    Attributes,
    Modifiers,
    FuncKeyword,
    Identifier,
    GenericParameterClause,
    Signature,
    GenericWhereClause,
    Body
  };

  using DataType = FunctionDeclSyntaxData;

  FunctionDeclSyntax(const RC<SyntaxData> Root, const DataType *Data)
    : Syntax(Root, Data) {}

public:
  /// Get the attributes of this function declaration.
  TypeAttributesSyntax getAttributes() const;

  /// Return a FunctionDeclSyntax with the given attributes.
  FunctionDeclSyntax withAttributes(TypeAttributesSyntax NewAttributes) const;

  /// Get the modifiers of this function declaration.
  DeclModifierListSyntax getModifiers() const;

  /// Return a FunctionDeclSyntax with the given modifiers.
  FunctionDeclSyntax withModifiers(DeclModifierListSyntax NewModifiers) const;

  /// Return the 'func' keyword of tis function declaration.
  RC<TokenSyntax> getFuncKeyword() const;

  /// Return a FunctionDeclSyntax with the given 'func' keyword.
  FunctionDeclSyntax withFuncKeyword(RC<TokenSyntax> NewFuncKeyword) const;

  /// Return the identifier of the function declaration.
  RC<TokenSyntax> getIdentifier() const;

  /// Return a FunctionDeclSyntax with the given identifier.
  FunctionDeclSyntax withIdentifier(RC<TokenSyntax> NewIdentifier) const;

  /// Return the generic parameter clause of the function declaration, if
  /// there is one. Otherwise, return llvm::None.
  llvm::Optional<GenericParameterClauseSyntax>
  getGenericParameterClause() const;

  /// Return a FunctionDeclSyntax with the given generic parameter clause.
  /// To remove the generic parameters, pass in llvm::None.
  FunctionDeclSyntax withGenericParameterClause(
    llvm::Optional<GenericParameterClauseSyntax> NewGenericParams) const;

  /// Return the signature of the function declaration.
  FunctionSignatureSyntax getSignature() const;

  /// Return a FunctionDeclSyntax with the given function signature.
  FunctionDeclSyntax withSignature(FunctionSignatureSyntax NewSignature) const;

  /// Return the body of the function declaration, if there is one.
  ///
  /// As an example, function declarations in protocols have no body.
  llvm::Optional<CodeBlockStmtSyntax> getBody() const;

  /// Return a FunctionDeclSyntax with the given body. To remove the body,
  /// pass in llvm::None.
  FunctionDeclSyntax
  withBody(llvm::Optional<CodeBlockStmtSyntax> NewBody) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::FunctionDecl;
  }
};

} // end namespace syntax
} // end namespace swift

#endif // SWIFT_SYNTAX_DECLSYNTAX_H
