//===--- ITCType.cpp - Iterative Type Checker for Types -------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://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(TR_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;
}

