//===--- IndexerQuery.h - A set of indexer query interfaces ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the base indexer queries that can be used with
// refactoring continuations.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLING_REFACTOR_INDEXER_QUERY_H
#define LLVM_CLANG_TOOLING_REFACTOR_INDEXER_QUERY_H

#include "clang/Tooling/Refactor/RefactoringOperationState.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Error.h"
#include <vector>

namespace clang {
namespace tooling {
namespace indexer {

/// Represents an abstract indexer query.
class IndexerQuery {
public:
  const char *BaseUID;
  const char *NameUID;

  IndexerQuery(const char *BaseUID, const char *NameUID)
      : BaseUID(BaseUID), NameUID(NameUID) {}
  virtual ~IndexerQuery() {}

  virtual void invalidateTUSpecificState() = 0;

  /// Checks if this query was satisfied. Returns true if it wasn't and reports
  /// appropriate errors.
  virtual bool verify(ASTContext &) { return false; }

  // Mainly used for testing.
  static llvm::Error loadResultsFromYAML(StringRef Source,
                                         ArrayRef<IndexerQuery *> Queries);

  static bool classof(const IndexerQuery *) { return true; }
};

/// An abstract AST query that can produce an AST unit in which the refactoring
/// continuation will run.
class ASTProducerQuery : public IndexerQuery {
  static const char *BaseUIDString;

public:
  /// Deriving AST producer queries can redefine this type to generate custom
  /// results that are then passed into the refactoring continuations.
  using ResultTy = void;

  ASTProducerQuery(const char *NameUID)
      : IndexerQuery(BaseUIDString, NameUID) {}

  static bool classof(const IndexerQuery *Q) {
    return Q->BaseUID == BaseUIDString;
  }
};

/// A query that finds a file that contains/should contain the implementation of
/// some declaration.
class ASTUnitForImplementationOfDeclarationQuery final
    : public ASTProducerQuery {
  static const char *NameUIDString;

  const Decl *D;
  PersistentFileID Result;

public:
  ASTUnitForImplementationOfDeclarationQuery(const Decl *D)
      : ASTProducerQuery(NameUIDString), D(D), Result("") {}

  using ResultTy = FileID;

  const Decl *getDecl() const { return D; }

  void invalidateTUSpecificState() override { D = nullptr; }

  void setResult(PersistentFileID File) { Result = std::move(File); }

  bool verify(ASTContext &Context) override;

  const PersistentFileID &getResult() const { return Result; }

  static bool classof(const IndexerQuery *D) {
    return D->NameUID == NameUIDString;
  }
};

/// Returns an indexer query that will allow a refactoring continuation to run
/// in an AST unit that contains a file that should contain the implementation
/// of the given declaration \p D.
///
/// The continuation function will receive \c FileID that corresponds to the
/// implementation file. The indexer can decide which file should be used as an
/// implementation of a declaration based on a number of different heuristics.
/// It does not guarantee that the file will actually have any declarations that
/// correspond to the implementation of \p D yet, as the indexer may decide to
/// point to a file that it thinks will have the implementation declarations in
/// the future.
std::unique_ptr<ASTUnitForImplementationOfDeclarationQuery>
fileThatShouldContainImplementationOf(const Decl *D);

/// A declaration predicate operates.
struct DeclPredicate {
  const char *Name;

  DeclPredicate(const char *Name) : Name(Name) {}

  bool operator==(const DeclPredicate &P) const {
    return StringRef(Name) == P.Name;
  }
  bool operator!=(const DeclPredicate &P) const {
    return StringRef(Name) != P.Name;
  }
};

/// Represents a declaration predicate that will evaluate to either 'true' or
/// 'false' in an indexer query.
struct BoolDeclPredicate {
  DeclPredicate Predicate;
  bool IsInverted;

  BoolDeclPredicate(DeclPredicate Predicate, bool IsInverted = false)
      : Predicate(Predicate), IsInverted(IsInverted) {}

  BoolDeclPredicate operator!() const {
    return BoolDeclPredicate(Predicate, /*IsInverted=*/!IsInverted);
  }
};

namespace detail {

/// AST-like representation for decl predicates.
class DeclPredicateNode {
public:
  const char *NameUID;
  DeclPredicateNode(const char *NameUID) : NameUID(NameUID) {}

  static std::unique_ptr<DeclPredicateNode>
  create(const DeclPredicate &Predicate);
  static std::unique_ptr<DeclPredicateNode>
  create(const BoolDeclPredicate &Predicate);

  static bool classof(const DeclPredicateNode *) { return true; }
};

class DeclPredicateNodePredicate : public DeclPredicateNode {
  static const char *NameUIDString;

  DeclPredicate Predicate;

public:
  DeclPredicateNodePredicate(const DeclPredicate &Predicate)
      : DeclPredicateNode(NameUIDString), Predicate(Predicate) {}

  const DeclPredicate &getPredicate() const { return Predicate; }

  static bool classof(const DeclPredicateNode *P) {
    return P->NameUID == NameUIDString;
  }
};

class DeclPredicateNotPredicate : public DeclPredicateNode {
  static const char *NameUIDString;

  std::unique_ptr<DeclPredicateNode> Child;

public:
  DeclPredicateNotPredicate(std::unique_ptr<DeclPredicateNode> Child)
      : DeclPredicateNode(NameUIDString), Child(std::move(Child)) {}

  const DeclPredicateNode &getChild() const { return *Child; }

  static bool classof(const DeclPredicateNode *P) {
    return P->NameUID == NameUIDString;
  }
};

} // end namespace detail

enum class QueryBoolResult {
  Unknown,
  Yes,
  No,
};

// FIXME: Check that 'T' is either a PersistentDeclRef<> or a Decl *.
template <typename T> struct Indexed {
  T Decl;
  // FIXME: Generalize better in the new refactoring engine.
  QueryBoolResult IsNotDefined;

  Indexed(T Decl, QueryBoolResult IsNotDefined = QueryBoolResult::Unknown)
      : Decl(Decl), IsNotDefined(IsNotDefined) {}

  Indexed(Indexed<T> &&Other) = default;
  Indexed &operator=(Indexed<T> &&Other) = default;
  Indexed(const Indexed<T> &Other) = default;
  Indexed &operator=(const Indexed<T> &Other) = default;

  /// True iff the declaration is not defined in the entire project.
  bool isNotDefined() const {
    // FIXME: This is hack. Need a better system in the new engine.
    return IsNotDefined == QueryBoolResult::Yes;
  }
};

/// Transforms one set of declarations into another using some predicate.
class DeclarationsQuery : public IndexerQuery {
  static const char *BaseUIDString;

  std::vector<const Decl *> Input;
  std::unique_ptr<detail::DeclPredicateNode> Predicate;

protected:
  std::vector<Indexed<PersistentDeclRef<Decl>>> Output;

public:
  DeclarationsQuery(std::vector<const Decl *> Input,
                    std::unique_ptr<detail::DeclPredicateNode> Predicate)
      : IndexerQuery(BaseUIDString, nullptr), Input(std::move(Input)),
        Predicate(std::move(Predicate)) {
    assert(!this->Input.empty() && "empty declarations list!");
  }

  ArrayRef<const Decl *> getInputs() const { return Input; }

  void invalidateTUSpecificState() override { Input.clear(); }

  bool verify(ASTContext &Context) override;

  void setOutput(std::vector<Indexed<PersistentDeclRef<Decl>>> Output) {
    this->Output = Output;
  }

  const detail::DeclPredicateNode &getPredicateNode() const {
    return *Predicate;
  }

  static bool classof(const IndexerQuery *Q) {
    return Q->BaseUID == BaseUIDString;
  }
};

/// The \c DeclEntity class acts as a proxy for the entity that represents a
/// declaration in the indexer. It defines a set of declaration predicates that
/// can be used in indexer queries.
struct DeclEntity {
  /// The indexer will evaluate this predicate to 'true' when a certain
  /// declaration has a corresponding definition.
  BoolDeclPredicate isDefined() const {
    return BoolDeclPredicate("decl.isDefined");
  }
};

template <typename T>
class ManyToManyDeclarationsQuery final
    : public std::enable_if<std::is_base_of<Decl, T>::value,
                            DeclarationsQuery>::type {
public:
  ManyToManyDeclarationsQuery(
      ArrayRef<const T *> Input,
      std::unique_ptr<detail::DeclPredicateNode> Predicate)
      : DeclarationsQuery(std::vector<const Decl *>(Input.begin(), Input.end()),
                          std::move(Predicate)) {}

  std::vector<Indexed<PersistentDeclRef<T>>> getOutput() const {
    std::vector<Indexed<PersistentDeclRef<T>>> Results;
    for (const auto &Ref : DeclarationsQuery::Output)
      Results.push_back(Indexed<PersistentDeclRef<T>>(
          PersistentDeclRef<T>(Ref.Decl.USR), Ref.IsNotDefined));
    return Results;
  }
};

/// Returns an indexer query that will pass a filtered list of declarations to
/// a refactoring continuation.
///
/// The filtering is done based on predicates that are available on the \c
/// DeclEntity types. For example, you can use the following invocation to
/// find a set of declarations that are defined in the entire project:
///
/// \code
/// filter({ MyDeclA, MyDeclB }, [] (const DeclEntity &D) { return D.isDefined()
/// })
/// \endcode
template <typename T>
std::unique_ptr<ManyToManyDeclarationsQuery<T>>
filter(ArrayRef<const T *> Declarations,
       BoolDeclPredicate (*Fn)(const DeclEntity &),
       typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
           nullptr) {
  return llvm::make_unique<ManyToManyDeclarationsQuery<T>>(
      Declarations, detail::DeclPredicateNode::create(Fn(DeclEntity())));
}

} // end namespace indexer
} // end namespace tooling
} // end namespace clang

#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_INDEXER_QUERY_H
