// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef CRUBIT_NULLABILITY_INFERENCE_COLLECT_EVIDENCE_H_
#define CRUBIT_NULLABILITY_INFERENCE_COLLECT_EVIDENCE_H_

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "nullability/inference/inference.proto.h"
#include "nullability/inference/slot_fingerprint.h"
#include "nullability/inference/usr_cache.h"
#include "nullability/pointer_nullability_analysis.h"
#include "nullability/pragma.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/Analysis/FlowSensitive/Solver.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"

namespace clang::tidy::nullability {

/// Describes the direction of flow for a piece of evidence between a virtual
/// method and its overrides.
enum class VirtualMethodEvidenceFlowDirection {
  kFromBaseToDerived,
  kFromDerivedToBase,
  kBoth,
};

/// Returns the direction of flow for a piece of evidence between a virtual
/// method and its overrides.
///
/// The direction is determined by whether the evidence points towards Nonnull
/// or Nullable and is for a return slot or a parameter slot.
VirtualMethodEvidenceFlowDirection getFlowDirection(Evidence::Kind Kind,
                                                    bool ForReturnSlot);

using RelatedVirtualMethodsMap = llvm::StringMap<llvm::StringSet<>>;

// Summarizes a method for the purpose of aligning evidence across
// virtual-method overrides.
struct MethodSummary {
  int SlotCount;
  // USRs of all methods that (transitively) override this method.
  llvm::StringSet<> OverridingUSRs;
};

struct VirtualMethodIndex {
  VirtualMethodIndex() = default;
  // These are expected to often be very large containers, so disallow copying.
  VirtualMethodIndex(const VirtualMethodIndex &) = delete;
  VirtualMethodIndex &operator=(const VirtualMethodIndex &) = delete;
  VirtualMethodIndex(VirtualMethodIndex &&) = default;
  VirtualMethodIndex &operator=(VirtualMethodIndex &&) = default;

  // Map from virtual methods in a TU to the set of methods that they
  // override. Methods are identified by USRs.
  RelatedVirtualMethodsMap Bases;
  // Map from virtual methods in a TU to the set of methods that override them
  // in that TU. Methods are identified by USRs.
  llvm::StringMap<MethodSummary> Overrides;
};

/// Index the relationships between virtual methods in the TU.
VirtualMethodIndex getVirtualMethodIndex(ASTContext &Ctx, USRCache &UC);

class SortedFingerprintVector {
 public:
  SortedFingerprintVector() = default;
  // These are expected to often be very large containers, so disallow copying.
  SortedFingerprintVector(const SortedFingerprintVector &) = delete;
  SortedFingerprintVector &operator=(const SortedFingerprintVector &) = delete;
  explicit SortedFingerprintVector(std::vector<SlotFingerprint> &&V)
      : Vector(std::move(V)) {
    if (!std::is_sorted(Vector.begin(), Vector.end())) {
      // Performance is much improved if the incoming vector is already sorted,
      // but this is not a requirement.
      llvm::errs() << "Previous inferences are not sorted. Performance may be "
                      "degraded.\n";
      std::sort(Vector.begin(), Vector.end());
    }
    const auto &FirstDuplicate =
        std::adjacent_find(Vector.begin(), Vector.end());
    if (FirstDuplicate != Vector.end()) {
      // Duplicate fingerprints are not expected, and can cause incorrect
      // inference results, but only for symbols that have the same fingerprint.
      // Do not crash, to avoid invalidating all the other results, but do log
      // as much debugging information as possible in case this very unexpected
      // event occurs.
      llvm::errs() << "Found duplicate fingerprints in previous inferences.\n";
      llvm::DenseMap<SlotFingerprint, int> AppearanceCounts;
      // Because the vector is sorted, we can count the number of appearances
      // starting from FirstDuplicate and know that there will be no duplicates
      // of any of the fingerprints from Vector.begin() until FirstDuplicate.
      for (auto It = FirstDuplicate; It != Vector.end(); ++It) {
        AppearanceCounts[*It]++;
      }
      for (const auto &[Fingerprint, Count] : AppearanceCounts) {
        if (Count > 1) {
          llvm::errs() << "Fingerprint " << Fingerprint << " appears " << Count
                       << " times.\n";
        }
      }
      // Remove the duplicates before continuing.
      Vector.erase(std::unique(Vector.begin(), Vector.end()), Vector.end());
    }
  }

  bool contains(SlotFingerprint Fingerprint) const {
    return std::binary_search(Vector.begin(), Vector.end(), Fingerprint);
  }

 private:
  std::vector<SlotFingerprint> Vector;
};

struct PreviousInferences {
  const std::shared_ptr<const SortedFingerprintVector> absl_nonnull Nullable =
      std::make_shared<const SortedFingerprintVector>();
  const std::shared_ptr<const SortedFingerprintVector> absl_nonnull Nonnull =
      std::make_shared<const SortedFingerprintVector>();
};

/// Creates a solver with default parameters that is suitable for passing to
/// `collectEvidenceFromDefinition()`.
std::unique_ptr<dataflow::Solver> makeDefaultSolverForInference();

/// Callback used to report collected nullability evidence.
using EvidenceEmitter = void(Evidence);

/// Creates an EvidenceEmitter that handles propagation of evidence for virtual
/// methods. This emitter caches USR generation, and should be reused for the
/// whole AST. All parameters must outlive the returned EvidenceEmitter.
llvm::unique_function<EvidenceEmitter> evidenceEmitterWithPropagation(
    llvm::unique_function<EvidenceEmitter> Emit, USRCache &USRCache,
    ASTContext &Ctx);

/// Creates an EvidenceEmitter as above, but allows re-use of a
/// VirtualMethodIndex.
llvm::unique_function<EvidenceEmitter> evidenceEmitterWithPropagation(
    llvm::unique_function<EvidenceEmitter> Emit, VirtualMethodIndex Index);

/// Analyze code (such as a function body or variable initializer) to infer
/// nullability.
///
/// Produces Evidence constraining the nullability slots of the symbols that
/// the code interacts with, such as the function's own parameters.
/// This is based on the code's behavior and our definition of null-safety.
///
/// It is up to the caller to ensure the definition is eligible for inference
/// (function has a body, is not dependent, etc).
llvm::Error collectEvidenceFromDefinition(
    const Decl &, llvm::function_ref<EvidenceEmitter>, USRCache &USRCache,
    const NullabilityPragmas &Pragmas,
    const PreviousInferences &PreviousInferences = {},
    const SolverFactory &MakeSolver = makeDefaultSolverForInference);

/// Gathers evidence of a symbol's nullability from a declaration of it.
///
/// These are trivial "inferences" of what's already written in the code. e.g:
///   void foo(Nullable<int*>);
/// The first parameter of foo must be nullable.
///
/// It is the caller's responsibility to ensure that the symbol is inferable.
void collectEvidenceFromTargetDeclaration(const clang::Decl &,
                                          llvm::function_ref<EvidenceEmitter>,
                                          USRCache &USRCache,
                                          const NullabilityPragmas &Pragmas);

/// Describes locations within an AST that provide evidence for use in
/// inference.
struct EvidenceSites {
  /// Declarations of inferable symbols.
  llvm::DenseSet<const Decl *absl_nonnull> Declarations;
  /// Definitions (e.g. function body, variable initializer) that can be
  /// analyzed.
  /// This will always be concrete code, not a template pattern. These may be
  /// passed to collectEvidenceFromDefinition().
  llvm::DenseSet<const Decl *absl_nonnull> Definitions;

  /// Find the evidence sites within the provided AST. If
  /// RestrictToMainFileOrHeader is true, only looks for evidence sites in the
  /// main file or its associated header. Implicit declarations are never
  /// considered to be in the main file or header.
  static EvidenceSites discover(ASTContext &,
                                bool RestrictToMainFileOrHeader = false);

  using ForEach = llvm::function_ref<void(const Decl &)>;
  /// For each evidence site with the provided AST, calls the provided
  /// callback(s). A single Decl may be passed to both callbacks if it is also a
  /// useful definition. If RestrictToMainFileOrHeader is true, only looks for
  /// evidence sites in the main file or its associated header. Implicit
  /// declarations are never considered to be in the main file or header.
  static void forDefinitionsAndForDeclarations(
      ForEach ForDefinitions, ForEach ForDeclarations, ASTContext &Ctx,
      bool RestrictToMainFileOrHeader = false);
};

/// Returns the slot number for the I'th parameter (0-based).
inline Slot paramSlot(unsigned I) { return static_cast<Slot>(SLOT_PARAM + I); }

}  // namespace clang::tidy::nullability

#endif  // CRUBIT_NULLABILITY_INFERENCE_COLLECT_EVIDENCE_H_
