//===--- 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 non-generic typealias.
  TypeAliasDecl,

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

  /// 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::GenericTypeAliasDecl:
    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 */
