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