//===--- EmptyCatchCheck.cpp - 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
//
//===----------------------------------------------------------------------===//

#include "EmptyCatchCheck.h"
#include "../utils/Matchers.h"
#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"
#include <algorithm>

using namespace clang::ast_matchers;
using ::clang::ast_matchers::internal::Matcher;

namespace clang::tidy::bugprone {

namespace {
AST_MATCHER(CXXCatchStmt, isInMacro) {
  return Node.getBeginLoc().isMacroID() || Node.getEndLoc().isMacroID() ||
         Node.getCatchLoc().isMacroID();
}

AST_MATCHER_P(CXXCatchStmt, hasHandler, Matcher<Stmt>, InnerMatcher) {
  Stmt *Handler = Node.getHandlerBlock();
  if (!Handler)
    return false;
  return InnerMatcher.matches(*Handler, Finder, Builder);
}

AST_MATCHER_P(CXXCatchStmt, hasCaughtType, Matcher<QualType>, InnerMatcher) {
  return InnerMatcher.matches(Node.getCaughtType(), Finder, Builder);
}

AST_MATCHER_P(CompoundStmt, hasAnyTextFromList, std::vector<llvm::StringRef>,
              List) {
  if (List.empty())
    return false;

  ASTContext &Context = Finder->getASTContext();
  SourceManager &SM = Context.getSourceManager();
  StringRef Text = Lexer::getSourceText(
      CharSourceRange::getTokenRange(Node.getSourceRange()), SM,
      Context.getLangOpts());
  return std::any_of(List.begin(), List.end(), [&](const StringRef &Str) {
    return Text.contains_insensitive(Str);
  });
}

} // namespace

EmptyCatchCheck::EmptyCatchCheck(StringRef Name, ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      IgnoreCatchWithKeywords(utils::options::parseStringList(
          Options.get("IgnoreCatchWithKeywords", "@TODO;@FIXME"))),
      AllowEmptyCatchForExceptions(utils::options::parseStringList(
          Options.get("AllowEmptyCatchForExceptions", ""))) {}

void EmptyCatchCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "IgnoreCatchWithKeywords",
                utils::options::serializeStringList(IgnoreCatchWithKeywords));
  Options.store(
      Opts, "AllowEmptyCatchForExceptions",
      utils::options::serializeStringList(AllowEmptyCatchForExceptions));
}

bool EmptyCatchCheck::isLanguageVersionSupported(
    const LangOptions &LangOpts) const {
  return LangOpts.CPlusPlus;
}

std::optional<TraversalKind> EmptyCatchCheck::getCheckTraversalKind() const {
  return TK_IgnoreUnlessSpelledInSource;
}

void EmptyCatchCheck::registerMatchers(MatchFinder *Finder) {
  auto AllowedNamedExceptionDecl =
      namedDecl(matchers::matchesAnyListedName(AllowEmptyCatchForExceptions));
  auto AllowedNamedExceptionTypes =
      qualType(anyOf(hasDeclaration(AllowedNamedExceptionDecl),
                     references(AllowedNamedExceptionDecl),
                     pointsTo(AllowedNamedExceptionDecl)));
  auto IgnoredExceptionType =
      qualType(anyOf(AllowedNamedExceptionTypes,
                     hasCanonicalType(AllowedNamedExceptionTypes)));

  Finder->addMatcher(
      cxxCatchStmt(unless(isExpansionInSystemHeader()), unless(isInMacro()),
                   unless(hasCaughtType(IgnoredExceptionType)),
                   hasHandler(compoundStmt(
                       statementCountIs(0),
                       unless(hasAnyTextFromList(IgnoreCatchWithKeywords)))))
          .bind("catch"),
      this);
}

void EmptyCatchCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *MatchedCatchStmt = Result.Nodes.getNodeAs<CXXCatchStmt>("catch");

  diag(
      MatchedCatchStmt->getCatchLoc(),
      "empty catch statements hide issues; to handle exceptions appropriately, "
      "consider re-throwing, handling, or avoiding catch altogether");
}

} // namespace clang::tidy::bugprone
