//===--- UseTransparentFunctorsCheck.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 "UseTransparentFunctorsCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace modernize {

UseTransparentFunctorsCheck::UseTransparentFunctorsCheck(
    StringRef Name, ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context), SafeMode(Options.get("SafeMode", false)) {}

void UseTransparentFunctorsCheck::storeOptions(
    ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "SafeMode", SafeMode);
}

void UseTransparentFunctorsCheck::registerMatchers(MatchFinder *Finder) {
  const auto TransparentFunctors =
      classTemplateSpecializationDecl(
          unless(hasAnyTemplateArgument(refersToType(voidType()))),
          hasAnyName("::std::plus", "::std::minus", "::std::multiplies",
                     "::std::divides", "::std::modulus", "::std::negate",
                     "::std::equal_to", "::std::not_equal_to", "::std::greater",
                     "::std::less", "::std::greater_equal", "::std::less_equal",
                     "::std::logical_and", "::std::logical_or",
                     "::std::logical_not", "::std::bit_and", "::std::bit_or",
                     "::std::bit_xor", "::std::bit_not"))
          .bind("FunctorClass");

  // Non-transparent functor mentioned as a template parameter. FIXIT.
  Finder->addMatcher(
      loc(qualType(
              unless(elaboratedType()),
              hasDeclaration(classTemplateSpecializationDecl(
                  unless(hasAnyTemplateArgument(templateArgument(refersToType(
                      qualType(pointsTo(qualType(isAnyCharacter()))))))),
                  hasAnyTemplateArgument(
                      templateArgument(refersToType(qualType(hasDeclaration(
                                           TransparentFunctors))))
                          .bind("Functor"))))))
          .bind("FunctorParentLoc"),
      this);

  if (SafeMode)
    return;

  // Non-transparent functor constructed. No FIXIT. There is no easy way
  // to rule out the problematic char* vs string case.
  Finder->addMatcher(cxxConstructExpr(hasDeclaration(cxxMethodDecl(
                                          ofClass(TransparentFunctors))),
                                      unless(isInTemplateInstantiation()))
                         .bind("FuncInst"),
                     this);
}

static const StringRef Message = "prefer transparent functors '%0<>'";

template <typename T> static T getInnerTypeLocAs(TypeLoc Loc) {
  T Result;
  while (Result.isNull() && !Loc.isNull()) {
    Result = Loc.getAs<T>();
    Loc = Loc.getNextTypeLoc();
  }
  return Result;
}

void UseTransparentFunctorsCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *FuncClass =
      Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("FunctorClass");
  if (const auto *FuncInst =
          Result.Nodes.getNodeAs<CXXConstructExpr>("FuncInst")) {
    diag(FuncInst->getBeginLoc(), Message) << FuncClass->getName();
    return;
  }

  const auto *Functor = Result.Nodes.getNodeAs<TemplateArgument>("Functor");
  const auto FunctorParentLoc =
      Result.Nodes.getNodeAs<TypeLoc>("FunctorParentLoc")
          ->getAs<TemplateSpecializationTypeLoc>();

  if (!FunctorParentLoc)
    return;

  unsigned ArgNum = 0;
  const auto *FunctorParentType =
      FunctorParentLoc.getType()->castAs<TemplateSpecializationType>();
  for (; ArgNum < FunctorParentType->getNumArgs(); ++ArgNum) {
    const TemplateArgument &Arg = FunctorParentType->getArg(ArgNum);
    if (Arg.getKind() != TemplateArgument::Type)
      continue;
    QualType ParentArgType = Arg.getAsType();
    if (ParentArgType->isRecordType() &&
        ParentArgType->getAsCXXRecordDecl() ==
            Functor->getAsType()->getAsCXXRecordDecl())
      break;
  }
  // Functor is a default template argument.
  if (ArgNum == FunctorParentType->getNumArgs())
    return;
  TemplateArgumentLoc FunctorLoc = FunctorParentLoc.getArgLoc(ArgNum);
  auto FunctorTypeLoc = getInnerTypeLocAs<TemplateSpecializationTypeLoc>(
      FunctorLoc.getTypeSourceInfo()->getTypeLoc());
  if (FunctorTypeLoc.isNull())
    return;

  SourceLocation ReportLoc = FunctorLoc.getLocation();
  if (ReportLoc.isInvalid())
    return;
  diag(ReportLoc, Message) << FuncClass->getName()
                           << FixItHint::CreateRemoval(
                                  FunctorTypeLoc.getArgLoc(0).getSourceRange());
}

} // namespace modernize
} // namespace tidy
} // namespace clang
