//===--- ITCType.cpp - Iterative Type Checker for Types -------------------===//
//
// 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 implements the portions of the IterativeTypeChecker
//  class that involve types.
//
//===----------------------------------------------------------------------===//
#include "GenericTypeResolver.h"
#include "TypeChecker.h"
#include "swift/Sema/IterativeTypeChecker.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTWalker.h"
#include "swift/AST/Decl.h"
using namespace swift;

//===----------------------------------------------------------------------===//
// Type resolution.
//===----------------------------------------------------------------------===//
bool IterativeTypeChecker::isResolveTypeReprSatisfied(
       std::tuple<TypeRepr *, DeclContext *, unsigned> payload) {
  auto typeRepr = std::get<0>(payload);
  auto options = static_cast<TypeResolutionOptions>(std::get<2>(payload));

  // FIXME: Introduce a bit indicating when everything in the TypeRepr
  // has been name-bound, which indicates that we can always compute a
  // structural type.
  struct FindUnboundTypeRepr : public ASTWalker {
    TypeResolutionOptions Options;

    // Whether we've found an unbound type.
    bool HasUnbound = false;

    FindUnboundTypeRepr(TypeResolutionOptions options) : Options(options) { }

    bool walkToTypeReprPre(TypeRepr *T) override {
      // If we already found an unbound type, we're done.
      if (HasUnbound) return false;

      if (auto ident = dyn_cast<ComponentIdentTypeRepr>(T)) {
        if (!ident->isBound()) {
          HasUnbound = true;
          return false;
        }

        // If we're only looking to resolve the structure of the type,
        // don't walk into generic arguments. They don't affect the
        // structure.
        if (Options.contains(TypeResolutionFlags::ResolveStructure) &&
            isa<GenericIdentTypeRepr>(ident))
          return false;
      }

      // Keep walking.
      return true;
    }
  } findUnboundTypeRepr(options);

  typeRepr->walk(findUnboundTypeRepr);
  return findUnboundTypeRepr.HasUnbound;
}

void IterativeTypeChecker::processResolveTypeRepr(
       std::tuple<TypeRepr *, DeclContext *, unsigned> payload,
       UnsatisfiedDependency unsatisfiedDependency) {
  auto typeRepr = std::get<0>(payload);
  auto dc = std::get<1>(payload);
  auto options = static_cast<TypeResolutionOptions>(std::get<2>(payload));
  
  // FIXME: TypeChecker::resolveType() is mostly non-ad-hoc-recursive
  // when given an UnsatisfiedDependency.
  TC.resolveType(typeRepr, dc, options, nullptr, &unsatisfiedDependency);
}

bool IterativeTypeChecker::breakCycleForResolveTypeRepr(
       std::tuple<TypeRepr *, DeclContext *, unsigned> payload) {
  std::get<0>(payload)->setInvalid();
  return true;
}

