//===--- TypeCheckType.h - Type Resolution Code ----------*- 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 utilities for resolving types.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SEMA_TYPE_CHECK_TYPE_H
#define SWIFT_SEMA_TYPE_CHECK_TYPE_H

#include "swift/AST/TypeResolutionStage.h"
#include "llvm/ADT/None.h"

namespace swift {

/// Flags that describe the context of type checking a pattern or
/// type.
enum class TypeResolutionFlags : uint16_t {
  /// Whether to allow unspecified types within a pattern.
  AllowUnspecifiedTypes = 1 << 0,

  /// Whether to allow unbound generic types.
  AllowUnboundGenerics = 1 << 1,

  /// Whether an unavailable protocol can be referenced.
  AllowUnavailableProtocol = 1 << 2,

  /// Whether we should allow references to unavailable types.
  AllowUnavailable = 1 << 3,

  /// Whether the given type can override the type of a typed pattern.
  OverrideType = 1 << 4,

  /// Whether we are validating the type for SIL.
  // FIXME: Move this flag to TypeResolverContext.
  SILType = 1 << 5,

  /// Whether we are parsing a SIL file.  Not the same as SILType,
  /// because the latter is not set if we're parsing an AST type.
  SILMode = 1 << 6,

  /// Whether this is a resolution based on a non-inferred type pattern.
  FromNonInferredPattern = 1 << 7,

  /// Whether this type resolution is guaranteed not to affect downstream files.
  KnownNonCascadingDependency = 1 << 8,

  /// Whether we are at the direct base of a type expression.
  Direct = 1 << 9,

  /// Whether we should not produce diagnostics if the type is invalid.
  SilenceErrors = 1 << 10,
};

/// Type resolution contexts that require special handling.
enum class TypeResolverContext : uint8_t {
  /// No special type handling is required.
  None,

  /// Whether we are checking the parameter list of a function.
  AbstractFunctionDecl,

  /// Whether we are checking the parameter list of a subscript.
  SubscriptDecl,

  /// Whether we are checking the parameter list of a closure.
  ClosureExpr,

  /// Whether we are in the input type of a function, or under one level of
  /// tuple type.  This is not set for multi-level tuple arguments.
  /// See also: TypeResolutionFlags::Direct
  FunctionInput,

  /// Whether this is a variadic function input.
  VariadicFunctionInput,

  /// Whether we are in the result type of a function, including multi-level
  /// tuple return values. See also: TypeResolutionFlags::Direct
  FunctionResult,

  /// Whether we are in the result type of a function body that is
  /// known to produce dynamic Self.
  DynamicSelfResult,

  /// Whether we are in a protocol's where clause
  ProtocolWhereClause,

  /// Whether this is a pattern binding entry.
  PatternBindingDecl,

  /// Whether we are the variable type in a for/in statement.
  ForEachStmt,

  /// Whether we are binding an extension declaration, which limits
  /// the lookup.
  ExtensionBinding,

  /// Whether this type is being used in an expression or local declaration.
  ///
  /// This affects what sort of dependencies are recorded when resolving the
  /// type.
  InExpression,

  /// Whether this type is being used in a cast or coercion expression.
  ExplicitCastExpr,

  /// Whether this type is the value carried in an enum case.
  EnumElementDecl,

  /// Whether this is the payload subpattern of an enum pattern.
  EnumPatternPayload,

  /// Whether we are checking the underlying type of a typealias.
  TypeAliasDecl,

  /// Whether we are in a requirement of a generic declaration
  GenericRequirement,

  /// Whether we are in a type argument for an optional
  ImmediateOptionalTypeArgument,

  /// Whether this is the type of an editor placeholder.
  EditorPlaceholderExpr,
};

/// Options that determine how type resolution should work.
class TypeResolutionOptions {
  using Context = TypeResolverContext;

  // The "base" type resolution context. This never changes.
  Context base = Context::None;
  // The current type resolution context.
  Context context = Context::None;
  // TypeResolutionFlags
  uint16_t flags = 0;
  static_assert(sizeof(TypeResolutionOptions::flags) ==
                    sizeof(TypeResolutionFlags),
                "Flags size error");

public:
  ~TypeResolutionOptions() = default;
  TypeResolutionOptions(const TypeResolutionOptions &) = default;
  TypeResolutionOptions(TypeResolutionOptions &&) = default;
  TypeResolutionOptions &operator =(const TypeResolutionOptions &) = default;
  TypeResolutionOptions &operator =(TypeResolutionOptions &&) = default;

  // NOTE: Use either setContext() or explicit construction and assignment.
  void operator =(const Context &) = delete;
  void operator =(Context &&) = delete;

  // NOTE: "None" might be more permissive than one wants, therefore no
  // reasonable default context is possible.
  TypeResolutionOptions() = delete;

  TypeResolutionOptions(Context context) : base(context), context(context),
      flags(unsigned(TypeResolutionFlags::Direct)) {}
  // Helper forwarding constructors:
  TypeResolutionOptions(llvm::NoneType) : TypeResolutionOptions(Context::None){}

  /// Test the current type resolution base context.
  bool hasBase(Context context) const { return base == context; }

  /// Get the base type resolution context.
  Context getBaseContext() const { return base; }

  /// Test the current type resolution context.
  bool is(Context context) const { return this->context == context; }

  /// Get the current type resolution context.
  Context getContext() const { return context; }
  /// Set the current type resolution context.
  void setContext(Context newContext) {
    context = newContext;
    flags &= ~unsigned(TypeResolutionFlags::Direct);
  }
  void setContext(llvm::NoneType) { setContext(Context::None); }

  /// Get the current flags.
  TypeResolutionFlags getFlags() const { return TypeResolutionFlags(flags); }

  /// Is this type resolution context an expression.
  bool isAnyExpr() const {
    switch (base) {
    case Context::InExpression:
    case Context::ExplicitCastExpr:
    case Context::ForEachStmt:
    case Context::PatternBindingDecl:
    case Context::EditorPlaceholderExpr:
    case Context::ClosureExpr:
      return true;
    case Context::None:
    case Context::FunctionInput:
    case Context::VariadicFunctionInput:
    case Context::FunctionResult:
    case Context::DynamicSelfResult:
    case Context::ProtocolWhereClause:
    case Context::ExtensionBinding:
    case Context::SubscriptDecl:
    case Context::EnumElementDecl:
    case Context::EnumPatternPayload:
    case Context::TypeAliasDecl:
    case Context::GenericRequirement:
    case Context::ImmediateOptionalTypeArgument:
    case Context::AbstractFunctionDecl:
      return false;
    }
    llvm_unreachable("unhandled kind");
  }

  /// Determine whether all of the given options are set.
  bool contains(TypeResolutionFlags set) const {
    return !static_cast<bool>(unsigned(set) & ~unsigned(flags));
  }

  /// Produce type resolution options with additional flags.
  friend TypeResolutionOptions operator|(TypeResolutionOptions lhs,
                                         TypeResolutionFlags rhs) {
    return lhs |= rhs;
  }

  /// Merge additional flags into type resolution options.
  friend TypeResolutionOptions &operator|=(TypeResolutionOptions &lhs,
                                           TypeResolutionFlags rhs) {
    lhs.flags |= unsigned(rhs);
    return lhs;
  }

  /// Test whether any given flag is set in the type resolution options.
  friend bool operator&(TypeResolutionOptions lhs, TypeResolutionFlags rhs) {
    return lhs.flags & unsigned(rhs);
  }

  /// Produce type resolution options with removed flags.
  friend TypeResolutionOptions operator-(TypeResolutionOptions lhs,
                                         TypeResolutionFlags rhs) {
    return lhs -= rhs;
  }

  /// Remove the flags from the type resolution options.
  friend TypeResolutionOptions &operator-=(TypeResolutionOptions &lhs,
                                           TypeResolutionFlags rhs) {
    lhs.flags &= ~unsigned(rhs);
    return lhs;
  }
  /// Strip the contextual options from the given type resolution options.
  inline TypeResolutionOptions withoutContext(bool preserveSIL = false) const {
    auto copy = *this;
    copy.setContext(None);
    // FIXME: Move SILType to TypeResolverContext.
    if (!preserveSIL) copy -= TypeResolutionFlags::SILType;
    return copy;
  }
};

/// Handles the resolution of types within a given declaration context,
/// which might involve resolving generic parameters to a particular
/// stage.
class TypeResolution {
  DeclContext *dc;
  TypeResolutionStage stage;

  union {
    /// The generic environment used to map to archetypes.
    GenericEnvironment *genericEnv;

    /// The generic signature
    struct {
      /// The generic signature to use for type resolution.
      GenericSignature *genericSig;

      /// The generic signature builder that will answer queries about
      /// generic types.
      mutable GenericSignatureBuilder *builder;
    } complete;
  };

  TypeResolution(DeclContext *dc, TypeResolutionStage stage)
    : dc(dc), stage(stage) { }

  GenericSignatureBuilder *getGenericSignatureBuilder() const;

public:
  /// Form a type resolution for the structure of a type, which does not
  /// attempt to resolve member types of type parameters to a particular
  /// associated type.
  static TypeResolution forStructural(DeclContext *dc);

  /// Form a type resolution for an interface type, which is a complete
  /// description of the type using generic parameters.
  static TypeResolution forInterface(DeclContext *dc);

  /// Form a type resolution for an interface type, which is a complete
  /// description of the type using generic parameters.
  static TypeResolution forInterface(DeclContext *dc,
                                     GenericSignature *genericSig);

  /// Form a type resolution for a contextual type, which is a complete
  /// description of the type using the archetypes of the given declaration
  /// context.
  static TypeResolution forContextual(DeclContext *dc);

  /// Form a type resolution for a contextual type, which is a complete
  /// description of the type using the archetypes of the given generic
  /// environment.
  static TypeResolution forContextual(DeclContext *dc,
                                      GenericEnvironment *genericEnv);

  /// Retrieve the ASTContext in which this resolution occurs.
  ASTContext &getASTContext() const { return dc->getASTContext(); }

  /// Retrieve the declaration context in which type resolution will be
  /// performed.
  DeclContext *getDeclContext() const { return dc; }

  /// Retrieve the type resolution stage.
  TypeResolutionStage getStage() const { return stage; }

  /// Retrieves the generic signature for the context, or NULL if there is
  /// no generic signature to resolve types.
  GenericSignature *getGenericSignature() const;

  /// \brief Resolves a TypeRepr to a type.
  ///
  /// Performs name binding, checking of generic arguments, and so on in order
  /// to create a well-formed type.
  ///
  /// \param TyR The type representation to check.
  ///
  /// \param options Options that alter type resolution.
  ///
  /// \returns a well-formed type or an ErrorType in case of an error.
  Type resolveType(TypeRepr *TyR, TypeResolutionOptions options);

  /// Whether this type resolution uses archetypes (vs. generic parameters).
  bool usesArchetypes() const;

  /// Map the given type (that involves generic parameters)
  Type mapTypeIntoContext(Type type) const;

  /// Resolve a reference to a member type of the given (dependent) base and
  /// name.
  Type resolveDependentMemberType(Type baseTy, DeclContext *DC,
                                  SourceRange baseRange,
                                  ComponentIdentTypeRepr *ref) const;

  /// Resolve an unqualified reference to an associated type or type alias
  /// in a protocol.
  Type resolveSelfAssociatedType(Type baseTy, DeclContext *DC,
                                 Identifier name) const;

  /// Determine whether the given two types are equivalent within this
  /// type resolution context.
  bool areSameType(Type type1, Type type2) const;
};

} // end namespace swift

#endif /* SWIFT_SEMA_TYPE_CHECK_TYPE_H */
