//===--- NameLookupRequests.h - Name Lookup Requests ------------*- 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 name-lookup requests.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_NAME_LOOKUP_REQUESTS_H
#define SWIFT_NAME_LOOKUP_REQUESTS_H

#include "swift/AST/SimpleRequest.h"
#include "swift/AST/ASTTypeIDs.h"
#include "swift/Basic/Statistic.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/TinyPtrVector.h"

namespace swift {

class ClassDecl;
class DestructorDecl;
class GenericContext;
class GenericParamList;
class TypeAliasDecl;
class TypeDecl;
namespace ast_scope {
class ASTScopeImpl;
class ScopeCreator;
} // namespace ast_scope

/// Display a nominal type or extension thereof.
void simple_display(
       llvm::raw_ostream &out,
       const llvm::PointerUnion<TypeDecl *, ExtensionDecl *> &value);

/// Describes a set of type declarations that are "direct" referenced by
/// a particular type in the AST.
using DirectlyReferencedTypeDecls = llvm::TinyPtrVector<TypeDecl *>;

/// Request the set of declarations directly referenced by the an "inherited"
/// type of a type or extension declaration.
///
/// This request retrieves the set of declarations that are directly referenced
/// by a particular type in the "inherited" clause of a type or extension
/// declaration. For example:
///
/// \code
///   protocol P { }
///   protocol Q { }
///   typealias Alias = P & Q
///   class C { }
///
///   class D: C, Alias { }
/// \endcode
///
/// The inherited declaration of \c D at index 0 is the class declaration C.
/// The inherited declaration of \c D at index 1 is the typealias Alias.
class InheritedDeclsReferencedRequest :
  public SimpleRequest<InheritedDeclsReferencedRequest,
                       DirectlyReferencedTypeDecls(
                         llvm::PointerUnion<TypeDecl *, ExtensionDecl *>,
                         unsigned),
                       CacheKind::Uncached> // FIXME: Cache these
{
public:
  using SimpleRequest::SimpleRequest;

private:
  friend SimpleRequest;

  // Evaluation.
  DirectlyReferencedTypeDecls evaluate(
      Evaluator &evaluator,
      llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
      unsigned index) const;

public:
  // Caching
  bool isCached() const { return true; }

  // Source location information.
  SourceLoc getNearestLoc() const;
};

/// Request the set of declarations directly referenced by the underlying
/// type of a typealias.
///
/// This request retrieves the set of type declarations that directly referenced
/// by the underlying type of a typealias. For example:
///
/// \code
///   protocol P { }
///   protocol Q { }
///   class C { }
///   typealias PQ = P & Q
///   typealias Alias = C & PQ
/// \endcode
///
/// The set of declarations referenced by the underlying type of \c PQ
/// contains both \c P and \c Q.
/// The set of declarations referenced by the underlying type of \c Alias
/// contains \c C and \c PQ. Clients can choose to look further into \c PQ
/// using another instance of this request.
class UnderlyingTypeDeclsReferencedRequest :
  public SimpleRequest<UnderlyingTypeDeclsReferencedRequest,
                       DirectlyReferencedTypeDecls(TypeAliasDecl *),
                       CacheKind::Uncached> // FIXME: Cache these
{
public:
  using SimpleRequest::SimpleRequest;

private:
  friend SimpleRequest;

  // Evaluation.
  DirectlyReferencedTypeDecls evaluate(
      Evaluator &evaluator,
      TypeAliasDecl *typealias) const;

public:
  // Caching
  bool isCached() const { return true; }
};

/// Request the superclass declaration for the given class.
class SuperclassDeclRequest :
    public SimpleRequest<SuperclassDeclRequest,
                         ClassDecl *(NominalTypeDecl *),
                         CacheKind::SeparatelyCached> {
public:
  using SimpleRequest::SimpleRequest;

private:
  friend SimpleRequest;

  // Evaluation.
  llvm::Expected<ClassDecl *>
  evaluate(Evaluator &evaluator, NominalTypeDecl *subject) const;

public:
  // Caching
  bool isCached() const { return true; }
  Optional<ClassDecl *> getCachedResult() const;
  void cacheResult(ClassDecl *value) const;
};

/// Request the nominal declaration extended by a given extension declaration.
class ExtendedNominalRequest :
    public SimpleRequest<ExtendedNominalRequest,
                         NominalTypeDecl *(ExtensionDecl *),
                         CacheKind::SeparatelyCached> {
public:
  using SimpleRequest::SimpleRequest;

private:
  friend SimpleRequest;

  // Evaluation.
  llvm::Expected<NominalTypeDecl *>
  evaluate(Evaluator &evaluator, ExtensionDecl *ext) const;

public:
  // Separate caching.
  bool isCached() const { return true; }
  Optional<NominalTypeDecl *> getCachedResult() const;
  void cacheResult(NominalTypeDecl *value) const;
};

struct SelfBounds {
  llvm::TinyPtrVector<NominalTypeDecl *> decls;
  bool anyObject = false;
};

/// Request the nominal types that occur as the right-hand side of "Self: Foo"
/// constraints in the "where" clause of a protocol extension.
class SelfBoundsFromWhereClauseRequest :
    public SimpleRequest<SelfBoundsFromWhereClauseRequest,
                         SelfBounds(llvm::PointerUnion<TypeDecl *,
                                                       ExtensionDecl *>),
                         CacheKind::Uncached> {
public:
  using SimpleRequest::SimpleRequest;

private:
  friend SimpleRequest;

  // Evaluation.
  SelfBounds evaluate(Evaluator &evaluator,
                      llvm::PointerUnion<TypeDecl *, ExtensionDecl *>) const;
};


/// Request all type aliases and nominal types that appear in the "where"
/// clause of an extension.
class TypeDeclsFromWhereClauseRequest :
    public SimpleRequest<TypeDeclsFromWhereClauseRequest,
                         DirectlyReferencedTypeDecls(ExtensionDecl *),
                         CacheKind::Uncached> {
public:
  using SimpleRequest::SimpleRequest;

private:
  friend SimpleRequest;

  // Evaluation.
  DirectlyReferencedTypeDecls evaluate(Evaluator &evaluator,
                                       ExtensionDecl *ext) const;
};

/// Request the nominal type declaration to which the given custom attribute
/// refers.
class CustomAttrNominalRequest :
    public SimpleRequest<CustomAttrNominalRequest,
                         NominalTypeDecl *(CustomAttr *, DeclContext *),
                         CacheKind::Cached> {
public:
  using SimpleRequest::SimpleRequest;

private:
  friend SimpleRequest;

  // Evaluation.
  llvm::Expected<NominalTypeDecl *>
  evaluate(Evaluator &evaluator, CustomAttr *attr, DeclContext *dc) const;

public:
  // Caching
  bool isCached() const { return true; }
};

/// Finds or synthesizes a destructor for the given class.
class GetDestructorRequest :
    public SimpleRequest<GetDestructorRequest,
                         DestructorDecl *(ClassDecl *),
                         CacheKind::SeparatelyCached> {
public:
  using SimpleRequest::SimpleRequest;

private:
  friend SimpleRequest;

  // Evaluation.
  llvm::Expected<DestructorDecl *>
  evaluate(Evaluator &evaluator, ClassDecl *classDecl) const;

public:
  // Caching
  bool isCached() const { return true; }
  Optional<DestructorDecl *> getCachedResult() const;
  void cacheResult(DestructorDecl *value) const;
};

class GenericParamListRequest :
    public SimpleRequest<GenericParamListRequest,
                         GenericParamList *(GenericContext *),
                         CacheKind::SeparatelyCached> {
public:
  using SimpleRequest::SimpleRequest;
  
private:
  friend SimpleRequest;
  
  // Evaluation.
  llvm::Expected<GenericParamList *>
  evaluate(Evaluator &evaluator, GenericContext *value) const;
  
public:
  // Separate caching.
  bool isCached() const { return true; }
  Optional<GenericParamList *> getCachedResult() const;
  void cacheResult(GenericParamList *value) const;
};

struct PrecedenceGroupDescriptor {
  DeclContext *dc;
  Identifier ident;
  SourceLoc nameLoc;

  SourceLoc getLoc() const;

  friend llvm::hash_code hash_value(const PrecedenceGroupDescriptor &owner) {
    return hash_combine(llvm::hash_value(owner.dc),
                        llvm::hash_value(owner.ident.getAsOpaquePointer()),
                        llvm::hash_value(owner.nameLoc.getOpaquePointerValue()));
  }

  friend bool operator==(const PrecedenceGroupDescriptor &lhs,
                         const PrecedenceGroupDescriptor &rhs) {
    return lhs.dc == rhs.dc &&
           lhs.ident == rhs.ident &&
           lhs.nameLoc == rhs.nameLoc;
  }

  friend bool operator!=(const PrecedenceGroupDescriptor &lhs,
                         const PrecedenceGroupDescriptor &rhs) {
    return !(lhs == rhs);
  }
};

void simple_display(llvm::raw_ostream &out, const PrecedenceGroupDescriptor &d);

class LookupPrecedenceGroupRequest
    : public SimpleRequest<LookupPrecedenceGroupRequest,
                           PrecedenceGroupDecl *(PrecedenceGroupDescriptor),
                           CacheKind::Cached> {
public:
  using SimpleRequest::SimpleRequest;

private:
  friend SimpleRequest;

  // Evaluation.
  llvm::Expected<PrecedenceGroupDecl *>
  evaluate(Evaluator &evaluator, PrecedenceGroupDescriptor descriptor) const;

public:
  // Source location
  SourceLoc getNearestLoc() const;
                               
  // Separate caching.
  bool isCached() const { return true; }
};

/// Expand the given ASTScope. Requestified to detect recursion.
class ExpandASTScopeRequest
    : public SimpleRequest<ExpandASTScopeRequest,
                           ast_scope::ASTScopeImpl *(ast_scope::ASTScopeImpl *,
                                                     ast_scope::ScopeCreator *),
                           CacheKind::SeparatelyCached> {
public:
  using SimpleRequest::SimpleRequest;

private:
  friend SimpleRequest;

  // Evaluation.
  llvm::Expected<ast_scope::ASTScopeImpl *>
  evaluate(Evaluator &evaluator, ast_scope::ASTScopeImpl *,
           ast_scope::ScopeCreator *) const;

public:
  // Separate caching.
  bool isCached() const;
  Optional<ast_scope::ASTScopeImpl *> getCachedResult() const;
  void cacheResult(ast_scope::ASTScopeImpl *) const {}
};

#define SWIFT_TYPEID_ZONE NameLookup
#define SWIFT_TYPEID_HEADER "swift/AST/NameLookupTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"
#undef SWIFT_TYPEID_ZONE
#undef SWIFT_TYPEID_HEADER

// Set up reporting of evaluated requests.
template<typename Request>
void reportEvaluatedRequest(UnifiedStatsReporter &stats,
                            const Request &request);

#define SWIFT_REQUEST(Zone, RequestType, Sig, Caching, LocOptions)             \
  template <>                                                                  \
  inline void reportEvaluatedRequest(UnifiedStatsReporter &stats,              \
                                     const RequestType &request) {             \
    ++stats.getFrontendCounters().RequestType;                                 \
  }
#include "swift/AST/NameLookupTypeIDZone.def"
#undef SWIFT_REQUEST

} // end namespace swift

#endif // SWIFT_NAME_LOOKUP_REQUESTS
