//===--- ClangTidyCheck.h - clang-tidy --------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H

#include "ClangTidyDiagnosticConsumer.h"
#include "ClangTidyOptions.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/Optional.h"
#include <type_traits>
#include <utility>
#include <vector>

namespace clang {

class CompilerInstance;
class SourceManager;

namespace tidy {

/// This class should be specialized by any enum type that needs to be converted
/// to and from an \ref llvm::StringRef.
template <class T> struct OptionEnumMapping {
  // Specializations of this struct must implement this function.
  static ArrayRef<std::pair<T, StringRef>> getEnumMapping() = delete;
};

/// Base class for all clang-tidy checks.
///
/// To implement a ``ClangTidyCheck``, write a subclass and override some of the
/// base class's methods. E.g. to implement a check that validates namespace
/// declarations, override ``registerMatchers``:
///
/// ~~~{.cpp}
/// void registerMatchers(ast_matchers::MatchFinder *Finder) override {
///   Finder->addMatcher(namespaceDecl().bind("namespace"), this);
/// }
/// ~~~
///
/// and then override ``check(const MatchResult &Result)`` to do the actual
/// check for each match.
///
/// A new ``ClangTidyCheck`` instance is created per translation unit.
///
/// FIXME: Figure out whether carrying information from one TU to another is
/// useful/necessary.
class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
public:
  /// Initializes the check with \p CheckName and \p Context.
  ///
  /// Derived classes must implement the constructor with this signature or
  /// delegate it. If a check needs to read options, it can do this in the
  /// constructor using the Options.get() methods below.
  ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);

  /// Override this to disable registering matchers and PP callbacks if an
  /// invalid language version is being used.
  ///
  /// For example if a check is examining overloaded functions then this should
  /// be overridden to return false when the CPlusPlus flag is not set in
  /// \p LangOpts.
  virtual bool isLanguageVersionSupported(const LangOptions &LangOpts) const {
    return true;
  }

  /// Override this to register ``PPCallbacks`` in the preprocessor.
  ///
  /// This should be used for clang-tidy checks that analyze preprocessor-
  /// dependent properties, e.g. include directives and macro definitions.
  ///
  /// This will only be executed if the function isLanguageVersionSupported
  /// returns true.
  ///
  /// There are two Preprocessors to choose from that differ in how they handle
  /// modular #includes:
  ///  - PP is the real Preprocessor. It doesn't walk into modular #includes and
  ///    thus doesn't generate PPCallbacks for their contents.
  ///  - ModuleExpanderPP preprocesses the whole translation unit in the
  ///    non-modular mode, which allows it to generate PPCallbacks not only for
  ///    the main file and textual headers, but also for all transitively
  ///    included modular headers when the analysis runs with modules enabled.
  ///    When modules are not enabled ModuleExpanderPP just points to the real
  ///    preprocessor.
  virtual void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
                                   Preprocessor *ModuleExpanderPP) {}

  /// Override this to register AST matchers with \p Finder.
  ///
  /// This should be used by clang-tidy checks that analyze code properties that
  /// dependent on AST knowledge.
  ///
  /// You can register as many matchers as necessary with \p Finder. Usually,
  /// "this" will be used as callback, but you can also specify other callback
  /// classes. Thereby, different matchers can trigger different callbacks.
  ///
  /// This will only be executed if the function isLanguageVersionSupported
  /// returns true.
  ///
  /// If you need to merge information between the different matchers, you can
  /// store these as members of the derived class. However, note that all
  /// matches occur in the order of the AST traversal.
  virtual void registerMatchers(ast_matchers::MatchFinder *Finder) {}

  /// ``ClangTidyChecks`` that register ASTMatchers should do the actual
  /// work in here.
  virtual void check(const ast_matchers::MatchFinder::MatchResult &Result) {}

  /// Add a diagnostic with the check's name.
  DiagnosticBuilder diag(SourceLocation Loc, StringRef Description,
                         DiagnosticIDs::Level Level = DiagnosticIDs::Warning);

  /// Add a diagnostic with the check's name.
  DiagnosticBuilder diag(StringRef Description,
                         DiagnosticIDs::Level Level = DiagnosticIDs::Warning);

  /// Adds a diagnostic to report errors in the check's configuration.
  DiagnosticBuilder
  configurationDiag(StringRef Description,
                    DiagnosticIDs::Level Level = DiagnosticIDs::Warning) const;

  /// Should store all options supported by this check with their
  /// current values or default values for options that haven't been overridden.
  ///
  /// The check should use ``Options.store()`` to store each option it supports
  /// whether it has the default value or it has been overridden.
  virtual void storeOptions(ClangTidyOptions::OptionMap &Options) {}

  /// Provides access to the ``ClangTidyCheck`` options via check-local
  /// names.
  ///
  /// Methods of this class prepend ``CheckName + "."`` to translate check-local
  /// option names to global option names.
  class OptionsView {
    void diagnoseBadIntegerOption(const Twine &Lookup,
                                  StringRef Unparsed) const;
    void diagnoseBadBooleanOption(const Twine &Lookup,
                                  StringRef Unparsed) const;
    void diagnoseBadEnumOption(const Twine &Lookup, StringRef Unparsed,
                               StringRef Suggestion = StringRef()) const;

  public:
    /// Initializes the instance using \p CheckName + "." as a prefix.
    OptionsView(StringRef CheckName,
                const ClangTidyOptions::OptionMap &CheckOptions,
                ClangTidyContext *Context);

    /// Read a named option from the ``Context``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present, return
    /// ``None``.
    llvm::Optional<std::string> get(StringRef LocalName) const;

    /// Read a named option from the ``Context``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present, returns
    /// \p Default.
    std::string get(StringRef LocalName, StringRef Default) const;

    /// Read a named option from the ``Context``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, return ``None``.
    llvm::Optional<std::string> getLocalOrGlobal(StringRef LocalName) const;

    /// Read a named option from the ``Context``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, returns \p Default.
    std::string getLocalOrGlobal(StringRef LocalName, StringRef Default) const;

    /// Read a named option from the ``Context`` and parse it as an
    /// integral type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present, return
    /// ``None``.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return ``None``.
    template <typename T>
    std::enable_if_t<std::is_integral<T>::value, llvm::Optional<T>>
    get(StringRef LocalName) const {
      if (llvm::Optional<std::string> Value = get(LocalName)) {
        T Result{};
        if (!StringRef(*Value).getAsInteger(10, Result))
          return Result;
        diagnoseBadIntegerOption(NamePrefix + LocalName, *Value);
      }
      return None;
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// integral type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present, return
    /// \p Default.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return \p Default.
    template <typename T>
    std::enable_if_t<std::is_integral<T>::value, T> get(StringRef LocalName,
                                                        T Default) const {
      return get<T>(LocalName).getValueOr(Default);
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// integral type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, return ``None``.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return ``None``.
    template <typename T>
    std::enable_if_t<std::is_integral<T>::value, llvm::Optional<T>>
    getLocalOrGlobal(StringRef LocalName) const {
      llvm::Optional<std::string> ValueOr = get(LocalName);
      bool IsGlobal = false;
      if (!ValueOr) {
        IsGlobal = true;
        ValueOr = getLocalOrGlobal(LocalName);
        if (!ValueOr)
          return None;
      }
      T Result{};
      if (!StringRef(*ValueOr).getAsInteger(10, Result))
        return Result;
      diagnoseBadIntegerOption(
          IsGlobal ? Twine(LocalName) : NamePrefix + LocalName, *ValueOr);
      return None;
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// integral type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, return \p Default.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return \p Default.
    template <typename T>
    std::enable_if_t<std::is_integral<T>::value, T>
    getLocalOrGlobal(StringRef LocalName, T Default) const {
      return getLocalOrGlobal<T>(LocalName).getValueOr(Default);
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// enum type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present, return
    /// ``None``.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return ``None``.
    ///
    /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
    /// supply the mapping required to convert between ``T`` and a string.
    template <typename T>
    std::enable_if_t<std::is_enum<T>::value, llvm::Optional<T>>
    get(StringRef LocalName, bool IgnoreCase = false) const {
      if (llvm::Optional<int64_t> ValueOr =
              getEnumInt(LocalName, typeEraseMapping<T>(), false, IgnoreCase))
        return static_cast<T>(*ValueOr);
      return None;
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// enum type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from the
    /// ``CheckOptions``. If the corresponding key is not present, return
    /// \p Default.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return \p Default.
    ///
    /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
    /// supply the mapping required to convert between ``T`` and a string.
    template <typename T>
    std::enable_if_t<std::is_enum<T>::value, T>
    get(StringRef LocalName, T Default, bool IgnoreCase = false) const {
      return get<T>(LocalName, IgnoreCase).getValueOr(Default);
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// enum type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either, returns ``None``.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return ``None``.
    ///
    /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
    /// supply the mapping required to convert between ``T`` and a string.
    template <typename T>
    std::enable_if_t<std::is_enum<T>::value, llvm::Optional<T>>
    getLocalOrGlobal(StringRef LocalName, bool IgnoreCase = false) const {
      if (llvm::Optional<int64_t> ValueOr =
              getEnumInt(LocalName, typeEraseMapping<T>(), true, IgnoreCase))
        return static_cast<T>(*ValueOr);
      return None;
    }

    /// Read a named option from the ``Context`` and parse it as an
    /// enum type ``T``.
    ///
    /// Reads the option with the check-local name \p LocalName from local or
    /// global ``CheckOptions``. Gets local option first. If local is not
    /// present, falls back to get global option. If global option is not
    /// present either return \p Default.
    ///
    /// If the corresponding key can't be parsed as a ``T``, emit a
    /// diagnostic and return \p Default.
    ///
    /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
    /// supply the mapping required to convert between ``T`` and a string.
    template <typename T>
    std::enable_if_t<std::is_enum<T>::value, T>
    getLocalOrGlobal(StringRef LocalName, T Default,
                     bool IgnoreCase = false) const {
      return getLocalOrGlobal<T>(LocalName, IgnoreCase).getValueOr(Default);
    }

    /// Stores an option with the check-local name \p LocalName with
    /// string value \p Value to \p Options.
    void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
               StringRef Value) const;

    /// Stores an option with the check-local name \p LocalName with
    /// integer value \p Value to \p Options.
    template <typename T>
    std::enable_if_t<std::is_integral<T>::value>
    store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
          T Value) const {
      storeInt(Options, LocalName, Value);
    }

    /// Stores an option with the check-local name \p LocalName as the string
    /// representation of the Enum \p Value to \p Options.
    ///
    /// \ref clang::tidy::OptionEnumMapping must be specialized for ``T`` to
    /// supply the mapping required to convert between ``T`` and a string.
    template <typename T>
    std::enable_if_t<std::is_enum<T>::value>
    store(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
          T Value) const {
      ArrayRef<std::pair<T, StringRef>> Mapping =
          OptionEnumMapping<T>::getEnumMapping();
      auto Iter = llvm::find_if(
          Mapping, [&](const std::pair<T, StringRef> &NameAndEnum) {
            return NameAndEnum.first == Value;
          });
      assert(Iter != Mapping.end() && "Unknown Case Value");
      store(Options, LocalName, Iter->second);
    }

  private:
    using NameAndValue = std::pair<int64_t, StringRef>;

    llvm::Optional<int64_t> getEnumInt(StringRef LocalName,
                                       ArrayRef<NameAndValue> Mapping,
                                       bool CheckGlobal, bool IgnoreCase) const;

    template <typename T>
    std::enable_if_t<std::is_enum<T>::value, std::vector<NameAndValue>>
    typeEraseMapping() const {
      ArrayRef<std::pair<T, StringRef>> Mapping =
          OptionEnumMapping<T>::getEnumMapping();
      std::vector<NameAndValue> Result;
      Result.reserve(Mapping.size());
      for (auto &MappedItem : Mapping) {
        Result.emplace_back(static_cast<int64_t>(MappedItem.first),
                            MappedItem.second);
      }
      return Result;
    }

    void storeInt(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
                  int64_t Value) const;


    std::string NamePrefix;
    const ClangTidyOptions::OptionMap &CheckOptions;
    ClangTidyContext *Context;
  };

private:
  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
  StringRef getID() const override { return CheckName; }
  std::string CheckName;
  ClangTidyContext *Context;

protected:
  OptionsView Options;
  /// Returns the main file name of the current translation unit.
  StringRef getCurrentMainFile() const { return Context->getCurrentFile(); }
  /// Returns the language options from the context.
  const LangOptions &getLangOpts() const { return Context->getLangOpts(); }
};

/// Read a named option from the ``Context`` and parse it as a bool.
///
/// Reads the option with the check-local name \p LocalName from the
/// ``CheckOptions``. If the corresponding key is not present, return
/// ``None``.
///
/// If the corresponding key can't be parsed as a bool, emit a
/// diagnostic and return ``None``.
template <>
llvm::Optional<bool>
ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName) const;

/// Read a named option from the ``Context`` and parse it as a bool.
///
/// Reads the option with the check-local name \p LocalName from the
/// ``CheckOptions``. If the corresponding key is not present, return
/// \p Default.
///
/// If the corresponding key can't be parsed as a bool, emit a
/// diagnostic and return \p Default.
template <>
llvm::Optional<bool>
ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName) const;

/// Stores an option with the check-local name \p LocalName with
/// bool value \p Value to \p Options.
template <>
void ClangTidyCheck::OptionsView::store<bool>(
    ClangTidyOptions::OptionMap &Options, StringRef LocalName,
    bool Value) const;


} // namespace tidy
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
