//===--- GenericParamList.h - Generic parameter list AST --------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 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 GenericParamList class, and related classes.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_GENERIC_PARAM_LIST_H
#define SWIFT_GENERIC_PARAM_LIST_H

#include "swift/AST/Decl.h"
#include "swift/AST/LayoutConstraint.h"
#include "swift/Basic/SourceLoc.h"
#include "llvm/ADT/StringRef.h"

namespace swift {

class ASTPrinter;
class TypeRepr;

enum class RequirementReprKind : unsigned {
  /// A type bound T : P, where T is a type that depends on a generic
  /// parameter and P is some type that should bound T, either as a concrete
  /// supertype or a protocol to which T must conform.
  TypeConstraint,

  /// A same-type requirement T == U, where T and U are types that shall be
  /// equivalent.
  SameType,

  /// A layout bound T : L, where T is a type that depends on a generic
  /// parameter and L is some layout specification that should bound T.
  LayoutConstraint,

  // Note: there is code that packs this enum in a 2-bit bitfield.  Audit users
  // when adding enumerators.
};

/// A single requirement in a 'where' clause, which places additional
/// restrictions on the generic parameters or associated types of a generic
/// function, type, or protocol.
///
/// This always represents a requirement spelled in the source code.  It is
/// never generated implicitly.
///
/// \c GenericParamList assumes these are POD-like.

class RequirementRepr {
  SourceLoc SeparatorLoc;
  RequirementReprKind Kind : 2;
  bool Invalid : 1;
  TypeRepr *FirstType;

  /// The second element represents the right-hand side of the constraint.
  /// It can be e.g. a type or a layout constraint.
  union {
    TypeRepr *SecondType;
    LayoutConstraintLoc SecondLayout;
  };

  /// Set during deserialization; used to print out the requirements accurately
  /// for the generated interface.
  StringRef AsWrittenString;

  RequirementRepr(SourceLoc SeparatorLoc, RequirementReprKind Kind,
                  TypeRepr *FirstType, TypeRepr *SecondType)
    : SeparatorLoc(SeparatorLoc), Kind(Kind), Invalid(false),
      FirstType(FirstType), SecondType(SecondType) { }

  RequirementRepr(SourceLoc SeparatorLoc, RequirementReprKind Kind,
                  TypeRepr *FirstType, LayoutConstraintLoc SecondLayout)
    : SeparatorLoc(SeparatorLoc), Kind(Kind), Invalid(false),
      FirstType(FirstType), SecondLayout(SecondLayout) { }

  void printImpl(ASTPrinter &OS) const;

public:
  /// Construct a new type-constraint requirement.
  ///
  /// \param Subject The type that must conform to the given protocol or
  /// composition, or be a subclass of the given class type.
  /// \param ColonLoc The location of the ':', or an invalid location if
  /// this requirement was implied.
  /// \param Constraint The protocol or protocol composition to which the
  /// subject must conform, or superclass from which the subject must inherit.
  static RequirementRepr getTypeConstraint(TypeRepr *Subject,
                                           SourceLoc ColonLoc,
                                           TypeRepr *Constraint) {
    return { ColonLoc, RequirementReprKind::TypeConstraint, Subject, Constraint };
  }

  /// Construct a new same-type requirement.
  ///
  /// \param FirstType The first type.
  /// \param EqualLoc The location of the '==' in the same-type constraint, or
  /// an invalid location if this requirement was implied.
  /// \param SecondType The second type.
  static RequirementRepr getSameType(TypeRepr *FirstType,
                                     SourceLoc EqualLoc,
                                     TypeRepr *SecondType) {
    return { EqualLoc, RequirementReprKind::SameType, FirstType, SecondType };
  }

  /// Construct a new layout-constraint requirement.
  ///
  /// \param Subject The type that must conform to the given layout 
  /// requirement.
  /// \param ColonLoc The location of the ':', or an invalid location if
  /// this requirement was implied.
  /// \param Layout The layout requirement to which the
  /// subject must conform.
  static RequirementRepr getLayoutConstraint(TypeRepr *Subject,
                                             SourceLoc ColonLoc,
                                             LayoutConstraintLoc Layout) {
    return {ColonLoc, RequirementReprKind::LayoutConstraint, Subject,
            Layout};
  }

  /// Determine the kind of requirement
  RequirementReprKind getKind() const { return Kind; }

  /// Determine whether this requirement is invalid.
  bool isInvalid() const { return Invalid; }

  /// Mark this requirement invalid.
  void setInvalid() { Invalid = true; }

  /// For a type-bound requirement, return the subject of the
  /// conformance relationship.
  TypeRepr *getSubjectRepr() const {
    assert(getKind() == RequirementReprKind::TypeConstraint ||
           getKind() == RequirementReprKind::LayoutConstraint);
    return FirstType;
  }

  /// For a type-bound requirement, return the protocol or to which
  /// the subject conforms or superclass it inherits.
  TypeRepr *getConstraintRepr() const {
    assert(getKind() == RequirementReprKind::TypeConstraint);
    return SecondType;
  }

  LayoutConstraint getLayoutConstraint() const {
    assert(getKind() == RequirementReprKind::LayoutConstraint);
    return SecondLayout.getLayoutConstraint();
  }

  LayoutConstraintLoc &getLayoutConstraintLoc() {
    assert(getKind() == RequirementReprKind::LayoutConstraint);
    return SecondLayout;
  }

  const LayoutConstraintLoc &getLayoutConstraintLoc() const {
    assert(getKind() == RequirementReprKind::LayoutConstraint);
    return SecondLayout;
  }

  /// Retrieve the first type of a same-type requirement.
  TypeRepr *getFirstTypeRepr() const {
    assert(getKind() == RequirementReprKind::SameType);
    return FirstType;
  }

  /// Retrieve the second type of a same-type requirement.
  TypeRepr *getSecondTypeRepr() const {
    assert(getKind() == RequirementReprKind::SameType);
    return SecondType;
  }

  /// Retrieve the location of the ':' or '==' in an explicitly-written
  /// conformance or same-type requirement respectively.
  SourceLoc getSeparatorLoc() const {
    return SeparatorLoc;
  }

  SourceRange getSourceRange() const;

  /// Retrieve the first or subject type representation from the \c repr,
  /// or \c nullptr if \c repr is null.
  static TypeRepr *getFirstTypeRepr(const RequirementRepr *repr) {
    if (!repr) return nullptr;
    return repr->FirstType;
  }

  /// Retrieve the second or constraint type representation from the \c repr,
  /// or \c nullptr if \c repr is null.
  static TypeRepr *getSecondTypeRepr(const RequirementRepr *repr) {
    if (!repr) return nullptr;
    assert(repr->getKind() == RequirementReprKind::TypeConstraint ||
           repr->getKind() == RequirementReprKind::SameType);
    return repr->SecondType;
  }

  SWIFT_DEBUG_DUMP;
  void print(raw_ostream &OS) const;
  void print(ASTPrinter &Printer) const;
};

using GenericParamSource = PointerUnion<GenericContext *, GenericParamList *>;

/// GenericParamList - A list of generic parameters that is part of a generic
/// function or type, along with extra requirements placed on those generic
/// parameters and types derived from them.
class GenericParamList final :
    private llvm::TrailingObjects<GenericParamList, GenericTypeParamDecl *> {
  friend TrailingObjects;

  SourceRange Brackets;
  unsigned NumParams;
  SourceLoc WhereLoc;
  MutableArrayRef<RequirementRepr> Requirements;

  GenericParamList *OuterParameters;

  GenericParamList(SourceLoc LAngleLoc,
                   ArrayRef<GenericTypeParamDecl *> Params,
                   SourceLoc WhereLoc,
                   MutableArrayRef<RequirementRepr> Requirements,
                   SourceLoc RAngleLoc);
  
  // Don't copy.
  GenericParamList(const GenericParamList &) = delete;
  GenericParamList &operator=(const GenericParamList &) = delete;
  
public:
  /// create - Create a new generic parameter list within the given AST context.
  ///
  /// \param Context The ASTContext in which the generic parameter list will
  /// be allocated.
  /// \param LAngleLoc The location of the opening angle bracket ('<')
  /// \param Params The list of generic parameters, which will be copied into
  /// ASTContext-allocated memory.
  /// \param RAngleLoc The location of the closing angle bracket ('>')
  static GenericParamList *create(ASTContext &Context,
                                  SourceLoc LAngleLoc,
                                  ArrayRef<GenericTypeParamDecl *> Params,
                                  SourceLoc RAngleLoc);

  /// create - Create a new generic parameter list and "where" clause within
  /// the given AST context.
  ///
  /// \param Context The ASTContext in which the generic parameter list will
  /// be allocated.
  /// \param LAngleLoc The location of the opening angle bracket ('<')
  /// \param Params The list of generic parameters, which will be copied into
  /// ASTContext-allocated memory.
  /// \param WhereLoc The location of the 'where' keyword, if any.
  /// \param Requirements The list of requirements, which will be copied into
  /// ASTContext-allocated memory.
  /// \param RAngleLoc The location of the closing angle bracket ('>')
  static GenericParamList *create(const ASTContext &Context,
                                  SourceLoc LAngleLoc,
                                  ArrayRef<GenericTypeParamDecl *> Params,
                                  SourceLoc WhereLoc,
                                  ArrayRef<RequirementRepr> Requirements,
                                  SourceLoc RAngleLoc);

  MutableArrayRef<GenericTypeParamDecl *> getParams() {
    return {getTrailingObjects<GenericTypeParamDecl *>(), NumParams};
  }

  ArrayRef<GenericTypeParamDecl *> getParams() const {
    return {getTrailingObjects<GenericTypeParamDecl *>(), NumParams};
  }

  using iterator = GenericTypeParamDecl **;
  using const_iterator = const GenericTypeParamDecl * const *;

  unsigned size() const { return NumParams; }
  iterator begin() { return getParams().begin(); }
  iterator end() { return getParams().end(); }
  const_iterator begin() const { return getParams().begin(); }
  const_iterator end() const { return getParams().end(); }

  /// Retrieve the location of the 'where' keyword, or an invalid
  /// location if 'where' was not present.
  SourceLoc getWhereLoc() const { return WhereLoc; }

  /// Retrieve the set of additional requirements placed on these
  /// generic parameters and types derived from them.
  ///
  /// This list may contain both explicitly-written requirements as well as
  /// implicitly-generated requirements, and may be non-empty even if no
  /// 'where' keyword is present.
  MutableArrayRef<RequirementRepr> getRequirements() { return Requirements; }

  /// Retrieve the set of additional requirements placed on these
  /// generic parameters and types derived from them.
  ///
  /// This list may contain both explicitly-written requirements as well as
  /// implicitly-generated requirements, and may be non-empty even if no
  /// 'where' keyword is present.
  ArrayRef<RequirementRepr> getRequirements() const { return Requirements; }
  
  /// Retrieve the outer generic parameter list.
  ///
  /// This is used for extensions of nested types, and in SIL mode, where a
  /// single lexical context can have multiple logical generic parameter
  /// lists.
  GenericParamList *getOuterParameters() const { return OuterParameters; }

  /// Set the outer generic parameter list. See \c getOuterParameters
  /// for more information.
  void setOuterParameters(GenericParamList *Outer) { OuterParameters = Outer; }

  void setDeclContext(DeclContext *dc);

  SourceLoc getLAngleLoc() const { return Brackets.Start; }
  SourceLoc getRAngleLoc() const { return Brackets.End; }

  SourceRange getSourceRange() const { return Brackets; }

  /// Retrieve the source range covering the where clause.
  SourceRange getWhereClauseSourceRange() const {
    if (WhereLoc.isInvalid())
      return SourceRange();

    if (Requirements.empty())
      return WhereLoc;

    auto endLoc = Requirements.back().getSourceRange().End;
    return SourceRange(WhereLoc, endLoc);
  }

  /// Configure the depth of the generic parameters in this list.
  void setDepth(unsigned depth);

  /// Create a copy of the generic parameter list and all of its generic
  /// parameter declarations. The copied generic parameters are re-parented
  /// to the given DeclContext.
  GenericParamList *clone(DeclContext *dc) const;

  void print(raw_ostream &OS) const;
  SWIFT_DEBUG_DUMP;

  bool walk(ASTWalker &walker);

  /// Finds a generic parameter declaration by name. This should only
  /// be used from the SIL parser.
  GenericTypeParamDecl *lookUpGenericParam(Identifier name) const;
};
  
/// A trailing where clause.
class alignas(RequirementRepr) TrailingWhereClause final :
    private llvm::TrailingObjects<TrailingWhereClause, RequirementRepr> {
  friend TrailingObjects;

  SourceLoc WhereLoc;
  SourceLoc EndLoc;

  /// The number of requirements. The actual requirements are tail-allocated.
  unsigned NumRequirements;

  TrailingWhereClause(SourceLoc whereLoc, SourceLoc endLoc,
                      ArrayRef<RequirementRepr> requirements);

public:
  /// Create a new trailing where clause with the given set of requirements.
  static TrailingWhereClause *create(ASTContext &ctx,
                                     SourceLoc whereLoc, SourceLoc endLoc,
                                     ArrayRef<RequirementRepr> requirements);

  /// Retrieve the location of the 'where' keyword.
  SourceLoc getWhereLoc() const { return WhereLoc; }

  /// Retrieve the set of requirements.
  MutableArrayRef<RequirementRepr> getRequirements() {
    return {getTrailingObjects<RequirementRepr>(), NumRequirements};
  }

  /// Retrieve the set of requirements.
  ArrayRef<RequirementRepr> getRequirements() const {
    return {getTrailingObjects<RequirementRepr>(), NumRequirements};
  }

  /// Compute the source range containing this trailing where clause.
  SourceRange getSourceRange() const {
    return SourceRange(WhereLoc, EndLoc);
  }

  void print(llvm::raw_ostream &OS, bool printWhereKeyword) const;

};

}  // namespace swift

#endif // SWIFT_GENERIC_PARAM_LIST_H