//===--- Matchers.h - clang-tidy-------------------------------------------===//
//
// 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_UTILS_MATCHERS_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_MATCHERS_H

#include "TypeTraits.h"
#include "clang/ASTMatchers/ASTMatchers.h"

namespace clang {
namespace tidy {
namespace matchers {

AST_MATCHER(BinaryOperator, isRelationalOperator) {
  return Node.isRelationalOp();
}

AST_MATCHER(BinaryOperator, isEqualityOperator) { return Node.isEqualityOp(); }

AST_MATCHER(QualType, isExpensiveToCopy) {
  llvm::Optional<bool> IsExpensive =
      utils::type_traits::isExpensiveToCopy(Node, Finder->getASTContext());
  return IsExpensive && *IsExpensive;
}

AST_MATCHER(RecordDecl, isTriviallyDefaultConstructible) {
  return utils::type_traits::recordIsTriviallyDefaultConstructible(
      Node, Finder->getASTContext());
}

AST_MATCHER(QualType, isTriviallyDestructible) {
  return utils::type_traits::isTriviallyDestructible(Node);
}

// Returns QualType matcher for references to const.
AST_MATCHER_FUNCTION(ast_matchers::TypeMatcher, isReferenceToConst) {
  using namespace ast_matchers;
  return referenceType(pointee(qualType(isConstQualified())));
}

// Returns QualType matcher for pointers to const.
AST_MATCHER_FUNCTION(ast_matchers::TypeMatcher, isPointerToConst) {
  using namespace ast_matchers;
  return pointerType(pointee(qualType(isConstQualified())));
}

// A matcher implementation that matches a list of type name regular expressions
// against a NamedDecl. If a regular expression contains the substring "::"
// matching will occur against the qualified name, otherwise only the typename.
class MatchesAnyListedNameMatcher
    : public ast_matchers::internal::MatcherInterface<NamedDecl> {
public:
  explicit MatchesAnyListedNameMatcher(llvm::ArrayRef<std::string> NameList) {
    std::transform(
        NameList.begin(), NameList.end(), std::back_inserter(NameMatchers),
        [](const llvm::StringRef Name) { return NameMatcher(Name); });
  }
  bool matches(
      const NamedDecl &Node, ast_matchers::internal::ASTMatchFinder *Finder,
      ast_matchers::internal::BoundNodesTreeBuilder *Builder) const override {
    return llvm::any_of(NameMatchers, [&Node](const NameMatcher &NM) {
      return NM.match(Node);
    });
  }

private:
  class NameMatcher {
    llvm::Regex Regex;
    enum class MatchMode {
      // Match against the unqualified name because the regular expression
      // does not contain ":".
      MatchUnqualified,
      // Match against the qualified name because the regular expression
      // contains ":" suggesting name and namespace should be matched.
      MatchQualified,
      // Match against the fully qualified name because the regular expression
      // starts with ":".
      MatchFullyQualified,
    };
    MatchMode Mode;

  public:
    NameMatcher(const llvm::StringRef Regex)
        : Regex(Regex), Mode(determineMatchMode(Regex)) {}

    bool match(const NamedDecl &ND) const {
      switch (Mode) {
      case MatchMode::MatchQualified:
        return Regex.match(ND.getQualifiedNameAsString());
      case MatchMode::MatchFullyQualified:
        return Regex.match("::" + ND.getQualifiedNameAsString());
      default:
        return Regex.match(ND.getName());
      }
    }

  private:
    MatchMode determineMatchMode(llvm::StringRef Regex) {
      if (Regex.startswith(":") || Regex.startswith("^:")) {
        return MatchMode::MatchFullyQualified;
      }
      return Regex.contains(":") ? MatchMode::MatchQualified
                                 : MatchMode::MatchUnqualified;
    }
  };

  std::vector<NameMatcher> NameMatchers;
};

// Returns a matcher that matches NamedDecl's against a list of provided regular
// expressions. If a regular expression contains starts ':' the NamedDecl's
// qualified name will be used for matching, otherwise its name will be used.
inline ::clang::ast_matchers::internal::Matcher<NamedDecl>
matchesAnyListedName(llvm::ArrayRef<std::string> NameList) {
  return ::clang::ast_matchers::internal::makeMatcher(
      new MatchesAnyListedNameMatcher(NameList));
}

} // namespace matchers
} // namespace tidy
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_MATCHERS_H
