//===--- 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 expression-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/SyntaxCollection.h"
#include "swift/Syntax/SyntaxCollectionData.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 {
  friend class FunctionParameterSyntax;
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;
  friend class SyntaxCollectionData<SyntaxKind::FunctionCallArgumentList,
                                    FunctionCallArgumentSyntax>;
  friend class SyntaxCollection<SyntaxKind::FunctionCallArgumentList,
                                FunctionCallArgumentSyntax>;

  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

using FunctionCallArgumentListSyntaxData =
  SyntaxCollectionData<SyntaxKind::FunctionCallArgumentList,
    FunctionCallArgumentSyntax>;

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

/// function-call-argument-list -> function-call-argument
///                                function-call-argument-list?
class FunctionCallArgumentListSyntax
  : public SyntaxCollection<SyntaxKind::FunctionCallArgumentList,
                            FunctionCallArgumentSyntax> {
  friend struct SyntaxFactory;
  friend class FunctionCallExprSyntax;
  friend class Syntax;
  friend class SyntaxData;

  using DataType = FunctionCallArgumentListSyntaxData;

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

public:
  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
