//===--- ExprSyntax.h - Swift Expression 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 expresion-specific syntax nodes,
// such as 
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SYNTAX_EXPRSYNTAX_H
#define SWIFT_SYNTAX_EXPRSYNTAX_H

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

using llvm::Optional;

namespace swift {
namespace syntax {

class GenericArgumentClauseSyntax;
class GenericArgumentClauseSyntaxData;

class ExprSyntaxData : public SyntaxData {
protected:
  ExprSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
                 CursorIndex IndexInParent = 0)
    : SyntaxData(Raw, Parent, IndexInParent) {
    assert(Raw->isExpr());
  }
public:
  static RC<ExprSyntaxData> make(RC<RawSyntax> Raw,
                                 const SyntaxData *Parent = nullptr,
                                 CursorIndex IndexInParent = 0);
  static RC<ExprSyntaxData> makeBlank();
  static bool classof(const SyntaxData *S) {
    return S->isExpr();
  }
};

class ExprSyntax : public Syntax {
public:
  using DataType = ExprSyntaxData;

  ExprSyntax(const RC<SyntaxData> Root, const ExprSyntaxData *Data);
  static bool classof(const Syntax *S) {
    return S->isExpr();
  }
};

#pragma mark - unknown-expression Data

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

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

#pragma mark - unknown-expression API

class UnknownExprSyntax : public UnknownSyntax {
  friend class SyntaxData;
  friend class UnknownExprSyntaxData;
  friend class LegacyASTTransformer;

  using DataType = UnknownExprSyntaxData;

public:
  UnknownExprSyntax(const RC<SyntaxData> Root,
                    const UnknownExprSyntaxData *Data);

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

#pragma mark - integer-literal-expression Data

class IntegerLiteralExprSyntaxData : public ExprSyntaxData {
  friend struct SyntaxFactory;
  friend class SyntaxData;

  IntegerLiteralExprSyntaxData(RC<RawSyntax> Raw,
                               const SyntaxData *Parent = nullptr,
                               CursorIndex IndexInParent = 0);
  static RC<IntegerLiteralExprSyntaxData> make(RC<RawSyntax> Raw,
                                       const SyntaxData *Parent = nullptr,
                                       CursorIndex IndexInParent = 0);
  static RC<IntegerLiteralExprSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::IntegerLiteralExpr;
  }
};

#pragma mark - integer-literal-expression API

class IntegerLiteralExprSyntax : public ExprSyntax {
  using DataType = IntegerLiteralExprSyntaxData;
  friend struct SyntaxFactory;
  friend class SyntaxData;
  friend class IntegerLiteralExprSyntaxData;

  IntegerLiteralExprSyntax(const RC<SyntaxData> Root,
                           const IntegerLiteralExprSyntaxData *Data);

  enum class Cursor : CursorIndex {
    Sign,
    Digits
  };

public:

  /// Get the '+' or '-' associated with this integer literal expression.
  RC<TokenSyntax> getSign() const;

  /// Return a new IntegerLiteralExprSyntax with the given '+' or '-' sign.
  IntegerLiteralExprSyntax withSign(RC<TokenSyntax> NewSign) const;

  /// Return the string of digits comprising the number part of the integer
  /// literal expression.
  RC<TokenSyntax> getDigits() const;

  /// Return a new IntegerLiteralExprSyntax with the given string of digits.
  IntegerLiteralExprSyntax withDigits(RC<TokenSyntax> NewDigits) const;

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

#pragma mark - symbolic-reference Data

class SymbolicReferenceExprSyntaxData : public ExprSyntaxData {
  friend class SymbolicReferenceExprSyntax;
  friend class SyntaxData;
  friend struct SyntaxFactory;

  RC<GenericArgumentClauseSyntaxData> CachedGenericArgClause;

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

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

  static RC<SymbolicReferenceExprSyntaxData> makeBlank();

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

#pragma mark - symbolic-reference API

/// symbolic-reference-expression -> identifier generic-argument-clause?
///
/// This is shown as primary-expression -> identifier generic-argument-clause?
/// in the grammar. It can be just an identifier referring to some
/// declaration, or it could perhaps be a constructor call to `Array<Int>`.
class SymbolicReferenceExprSyntax : public ExprSyntax {

  using DataType = SymbolicReferenceExprSyntaxData;

  friend struct SyntaxFactory;
  friend class SyntaxData;
  friend class Syntax;
  friend class SymbolicReferenceExprSyntaxData;

  enum class Cursor : CursorIndex {
    Identifier,
    GenericArgumentClause
  };

  SymbolicReferenceExprSyntax(const RC<SyntaxData> Root,
                              const DataType *Data);

public:

  /// Get the identifier for the symbol to which this expression refers.
  RC<TokenSyntax> getIdentifier() const;

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

  /// Return the generic arguments this symbolic reference has, if it has one.
  llvm::Optional<GenericArgumentClauseSyntax> getGenericArgumentClause() const;

  /// Return a new `SymbolicReferenceExprSyntax` with the given generic
  /// arguments.
  SymbolicReferenceExprSyntax
  withGenericArgumentClause(GenericArgumentClauseSyntax NewGenericArgs) const;

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

#pragma mark - function-call-argument Data

class FunctionCallArgumentSyntaxData : public SyntaxData {
  friend struct SyntaxFactory;
  friend class FunctionCallArgumentSyntax;
  friend class SyntaxData;

  RC<ExprSyntaxData> CachedExpression;

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

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

  static RC<FunctionCallArgumentSyntaxData> makeBlank();

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

#pragma mark - function-call-argument API

/// function-call-argument -> label? ':'? (expression | operator) ','?
class FunctionCallArgumentSyntax : public Syntax {

  using DataType = FunctionCallArgumentSyntaxData;

  friend struct SyntaxFactory;
  friend class SyntaxData;
  friend class Syntax;
  friend class FunctionCallArgumentSyntaxData;
  friend class FunctionCallArgumentListSyntax;

  enum class Cursor {
    Label,
    Colon,
    Expression,
    Comma,
  };

  FunctionCallArgumentSyntax(const RC<SyntaxData> Root,
                             const DataType *Data);

public:

  /// Return the label identifier for this argument, if it has one.
  RC<TokenSyntax> getLabel() const;

  /// Return a new `FunctionCallArgumentSyntax` with the given label.
  FunctionCallArgumentSyntax withLabel(RC<TokenSyntax> NewLabel) const;

  /// Get the colon ':' token in between the label and argument,
  /// if there is one.
  RC<TokenSyntax> getColonToken() const;

  /// Return a new `FunctionCallArgumentSyntax` with the given colon ':' token.
  FunctionCallArgumentSyntax withColonToken(RC<TokenSyntax> NewColon) const;

  /// Returns the expression of the argument.
  llvm::Optional<ExprSyntax> getExpression() const;

  /// Return a new `FunctionCallArgumentSyntax` with the given expression
  /// argument.
  FunctionCallArgumentSyntax withExpression(ExprSyntax NewExpression) const;

  /// Get the comma ',' token immediately following this argument, if there
  /// is one.
  RC<TokenSyntax> getTrailingComma() const;

  /// Return a new `FunctionCallArgumentSyntax` with the given comma attached
  /// to the end of the argument.
  FunctionCallArgumentSyntax
  withTrailingComma(RC<TokenSyntax> NewTrailingComma) const;

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

#pragma mark - function-call-argument-list Data

class FunctionCallArgumentListSyntaxData : public SyntaxData {
  friend struct SyntaxFactory;
  friend class FunctionCallArgumentListSyntax;
  friend class FunctionCallExprSyntaxBuilder;
  friend class SyntaxData;

  std::vector<RC<FunctionCallArgumentSyntaxData>> CachedArguments;

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

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

  static RC<FunctionCallArgumentListSyntaxData> makeBlank();

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

#pragma mark - function-call-argument-list API

/// function-call-argument-list -> function-call-argument
///                                function-call-argument-list?
class FunctionCallArgumentListSyntax : public Syntax {
  friend struct SyntaxFactory;
  friend class FunctionCallArgumentListSyntaxData;
  friend class FunctionCallExprSyntax;
  friend class Syntax;
  friend class SyntaxData;

  using DataType = FunctionCallArgumentListSyntaxData;

  FunctionCallArgumentListSyntax(const RC<SyntaxData> Root,
                                 const DataType *Data);

public:
  /// Return the number of arguments in this list.
  size_t getNumArguments() const;

  /// Get the argument at the given Index.
  FunctionCallArgumentSyntax getArgument(size_t n) const;

  /// Returns a new `FunctionCallArgumentListSyntax` with the given
  /// argument added to the end.
  FunctionCallArgumentListSyntax
  withAdditionalArgument(FunctionCallArgumentSyntax AdditionalArgument) const;

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

#pragma mark - function-call-expression Data

class FunctionCallExprSyntaxData : public ExprSyntaxData {
  friend struct SyntaxFactory;
  friend class FunctionCallExprSyntax;
  friend class FunctionCallExprSyntaxBuilder;
  friend class SyntaxData;

  RC<ExprSyntaxData> CachedCalledExpression;
  RC<FunctionCallArgumentListSyntaxData> CachedArgumentList;

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

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

  static RC<FunctionCallExprSyntaxData> makeBlank();

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

#pragma mark - function-call-expression API

class FunctionCallExprSyntax : public ExprSyntax {
  using DataType = FunctionCallExprSyntaxData;
  friend struct SyntaxFactory;
  friend class FunctionCallExprSyntaxData;
  friend class FunctionCallExprSyntaxBuilder;
  friend class Syntax;
  friend class SyntaxData;

  enum class Cursor: CursorIndex {
    CalledExpression,
    LeftParen,
    ArgumentList,
    RightParen,
  };

  FunctionCallExprSyntax(const RC<SyntaxData> Root, const DataType *Data);

public:

  /// Get the base expression getting called.
  ExprSyntax getCalledExpression() const;

  /// Return a new `FunctionCallExprSyntax` with the given base expression
  /// to be called.
  FunctionCallExprSyntax
  withCalledExpression(ExprSyntax NewBaseExpression) const;

  /// Return the left parenthesis '(' token in this call.
  RC<TokenSyntax> getLeftParen() const;

  /// Return a new `FunctionCallExprSyntax` with the given left parenthesis '('
  /// token.
  FunctionCallExprSyntax withLeftParen(RC<TokenSyntax> NewLeftParen) const;

  /// Get the list of arguments in this call expression.
  FunctionCallArgumentListSyntax getArgumentList() const;

  /// Return a new `FunctionCallExprSyntax` with the given argument list.
  FunctionCallExprSyntax
  withArgumentList(FunctionCallArgumentListSyntax NewArgumentList) const;

  /// Return the right parenthesis ')' token in this call.
  RC<TokenSyntax> getRightParen() const;

  /// Return a new `FunctionCallExprSyntax` with the given right parenthesis ')'
  /// token.
  FunctionCallExprSyntax withRightParen(RC<TokenSyntax> NewLeftParen) const;

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

#pragma mark - function-call-argument-list-builder
class FunctionCallExprSyntaxBuilder {
  RawSyntax::LayoutList CallLayout;
  RawSyntax::LayoutList ListLayout;
public:

  /// Start the builder with all elements marked as missing or empty.
  FunctionCallExprSyntaxBuilder();

  /// Use the given expression as the call target.
  FunctionCallExprSyntaxBuilder &
  useCalledExpression(ExprSyntax CalledExpression);

  /// Use the given left parenthesis '(' token in the function call.
  FunctionCallExprSyntaxBuilder &useLeftParen(RC<TokenSyntax> LeftParen);

  /// Add an additional argument to the layout.
  FunctionCallExprSyntaxBuilder &
  appendArgument(FunctionCallArgumentSyntax AdditionalArgument);

  /// Use the given right parenthesis ')' token in the function call.
  FunctionCallExprSyntaxBuilder &useRightParen(RC<TokenSyntax> RightParen);

  /// Return a `FunctionCallExprSyntax` with the arguments added so far.
  FunctionCallExprSyntax build() const;
};

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

#endif // SWIFT_SYNTAX_EXPRSYNTAX_H
