//===--- ITCNameLookup.cpp - Iterative Type Checker Name Lookup -----------===//
//
// 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 name lookup.
//
//===----------------------------------------------------------------------===//
#include "TypeChecker.h"
#include "swift/Sema/IterativeTypeChecker.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include <tuple>
using namespace swift;

//===----------------------------------------------------------------------===//
// Qualified name lookup handling
//===----------------------------------------------------------------------===//
bool IterativeTypeChecker::isQualifiedLookupInDeclContextSatisfied(
       TypeCheckRequest::DeclContextLookupPayloadType payload) {
  auto dc = payload.DC;

  NominalTypeDecl *nominal = nullptr;
  switch (dc->getContextKind()) {
  case DeclContextKind::AbstractClosureExpr:
  case DeclContextKind::AbstractFunctionDecl:
  case DeclContextKind::Initializer:
  case DeclContextKind::TopLevelCodeDecl:
  case DeclContextKind::SerializedLocal:
  case DeclContextKind::SubscriptDecl:
    llvm_unreachable("not a DeclContext that supports name lookup");

  case DeclContextKind::Module:
  case DeclContextKind::FileUnit:
    // Modules and file units can always handle name lookup.
    return true;

  case DeclContextKind::GenericTypeDecl:
    // Get the nominal type.
    nominal = dyn_cast<NominalTypeDecl>(cast<GenericTypeDecl>(dc));
    if (!nominal) return true;
    break;

  case DeclContextKind::ExtensionDecl: {
    auto ext = cast<ExtensionDecl>(dc);
    // FIXME: bind the extension. We currently assume this is done.
    nominal = ext->getAsNominalTypeOrNominalTypeExtensionContext();
    if (!nominal) return true;
    break;
  }
  }

  assert(nominal && "Only nominal types are handled here");
  // FIXME: Cache a bit indicating when qualified lookup is possible.

  // If we needed them for this query, did we already add implicit
  // initializers?
  auto name = payload.Name;
  if ((!name || name.matchesRef(getASTContext().Id_init)) &&
      !nominal->addedImplicitInitializers())
    return false;

  // For classes, check the superclass.
  if (auto classDecl = dyn_cast<ClassDecl>(nominal)) {
    if (!isSatisfied(requestTypeCheckSuperclass(classDecl)))
      return false;

    if (auto superclass = classDecl->getSuperclass()) {
      if (auto superclassDecl = superclass->getAnyNominal()) {
        // Hack.
        if (superclassDecl == nominal)
          return true;

        if (!isSatisfied(requestQualifiedLookupInDeclContext({ superclassDecl,
                                                               payload.Name,
                                                               payload.Loc })))
          return false;
      }
    }
  }

  return true;
}

void IterativeTypeChecker::processQualifiedLookupInDeclContext(
       TypeCheckRequest::DeclContextLookupPayloadType payload,
       UnsatisfiedDependency unsatisfiedDependency) {
  auto nominal = payload.DC->getAsNominalTypeOrNominalTypeExtensionContext();
  assert(nominal && "Only nominal types are handled here");

  // For classes, we need the superclass (if any) to support qualified lookup.
  if (auto classDecl = dyn_cast<ClassDecl>(nominal)) {
    if (unsatisfiedDependency(requestTypeCheckSuperclass(classDecl)))
      return;

    if (auto superclass = classDecl->getSuperclass()) {
      if (auto superclassDecl = superclass->getAnyNominal()) {
        if (unsatisfiedDependency(
              requestQualifiedLookupInDeclContext({ superclassDecl,
                                                    payload.Name,
                                                    payload.Loc })))
          return;
      }
    }
  }

  // FIXME: we need to resolve the set of protocol conformances to do
  // unqualified lookup.

  // If we're looking for all names or for an initializer, resolve
  // implicitly-declared initializers.
  // FIXME: Recursion into old type checker.
  auto name = payload.Name;
  if (!name || name.matchesRef(getASTContext().Id_init))
    TC.resolveImplicitConstructors(nominal);
}

bool IterativeTypeChecker::breakCycleForQualifiedLookupInDeclContext(
       TypeCheckRequest::DeclContextLookupPayloadType payload) {
  return false;
}

//===----------------------------------------------------------------------===//
// Qualified name lookup handling
//===----------------------------------------------------------------------===//
bool IterativeTypeChecker::isUnqualifiedLookupInDeclContextSatisfied(
       TypeCheckRequest::DeclContextLookupPayloadType payload) {
  auto dc = payload.DC;
  switch (dc->getContextKind()) {
  case DeclContextKind::AbstractClosureExpr:
  case DeclContextKind::AbstractFunctionDecl:
  case DeclContextKind::SubscriptDecl:
  case DeclContextKind::Initializer:
  case DeclContextKind::TopLevelCodeDecl:
  case DeclContextKind::SerializedLocal:
    // FIXME: Actually do the lookup in these contexts, because if we find
    // something, we don't need to continue outward.
    return isUnqualifiedLookupInDeclContextSatisfied({dc->getParent(),
                                                      payload.Name,
                                                      payload.Loc});

  case DeclContextKind::Module:
  case DeclContextKind::FileUnit:
    // Modules and file units can always handle name lookup.
    return true;

  case DeclContextKind::GenericTypeDecl:
  case DeclContextKind::ExtensionDecl:
    // Check whether we can perform qualified lookup into this
    // declaration context.
    if (!isSatisfied(
          requestQualifiedLookupInDeclContext({dc, payload.Name, payload.Loc})))
      return false;
      
    // FIXME: If there is a name, actually perform qualified lookup
    // into this DeclContext. If it succeeds, there's nothing more to
    // do.
    return isUnqualifiedLookupInDeclContextSatisfied({dc->getParent(),
                                                      payload.Name,
                                                      payload.Loc});
  }

  llvm_unreachable("Unhandled DeclContextKind in switch.");
}

void IterativeTypeChecker::processUnqualifiedLookupInDeclContext(
       TypeCheckRequest::DeclContextLookupPayloadType payload,
       UnsatisfiedDependency unsatisfiedDependency) {
  // Everything is handled by the dependencies.
}

bool IterativeTypeChecker::breakCycleForUnqualifiedLookupInDeclContext(
       TypeCheckRequest::DeclContextLookupPayloadType payload) {
  return false;
}
