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

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace google {

static const llvm::StringRef RenameCaseToSuiteMessage =
    "Google Test APIs named with 'case' are deprecated; use equivalent APIs "
    "named with 'suite'";

static llvm::Optional<llvm::StringRef>
getNewMacroName(llvm::StringRef MacroName) {
  std::pair<llvm::StringRef, llvm::StringRef> ReplacementMap[] = {
      {"TYPED_TEST_CASE", "TYPED_TEST_SUITE"},
      {"TYPED_TEST_CASE_P", "TYPED_TEST_SUITE_P"},
      {"REGISTER_TYPED_TEST_CASE_P", "REGISTER_TYPED_TEST_SUITE_P"},
      {"INSTANTIATE_TYPED_TEST_CASE_P", "INSTANTIATE_TYPED_TEST_SUITE_P"},
      {"INSTANTIATE_TEST_CASE_P", "INSTANTIATE_TEST_SUITE_P"},
  };

  for (auto &Mapping : ReplacementMap) {
    if (MacroName == Mapping.first)
      return Mapping.second;
  }

  return llvm::None;
}

namespace {

class UpgradeGoogletestCasePPCallback : public PPCallbacks {
public:
  UpgradeGoogletestCasePPCallback(UpgradeGoogletestCaseCheck *Check,
                                  Preprocessor *PP)
      : ReplacementFound(false), Check(Check), PP(PP) {}

  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
                    SourceRange Range, const MacroArgs *) override {
    macroUsed(MacroNameTok, MD, Range.getBegin(), CheckAction::Rename);
  }

  void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD,
                      const MacroDirective *Undef) override {
    if (Undef != nullptr)
      macroUsed(MacroNameTok, MD, Undef->getLocation(), CheckAction::Warn);
  }

  void MacroDefined(const Token &MacroNameTok,
                    const MacroDirective *MD) override {
    if (!ReplacementFound && MD != nullptr) {
      // We check if the newly defined macro is one of the target replacements.
      // This ensures that the check creates warnings only if it is including a
      // recent enough version of Google Test.
      llvm::StringRef FileName = PP->getSourceManager().getFilename(
          MD->getMacroInfo()->getDefinitionLoc());
      ReplacementFound = FileName.endswith("gtest/gtest-typed-test.h") &&
                         PP->getSpelling(MacroNameTok) == "TYPED_TEST_SUITE";
    }
  }

  void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
               SourceRange Range) override {
    macroUsed(MacroNameTok, MD, Range.getBegin(), CheckAction::Warn);
  }

  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
             const MacroDefinition &MD) override {
    macroUsed(MacroNameTok, MD, Loc, CheckAction::Warn);
  }

  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
              const MacroDefinition &MD) override {
    macroUsed(MacroNameTok, MD, Loc, CheckAction::Warn);
  }

private:
  enum class CheckAction { Warn, Rename };

  void macroUsed(const clang::Token &MacroNameTok, const MacroDefinition &MD,
                 SourceLocation Loc, CheckAction Action) {
    if (!ReplacementFound)
      return;

    std::string Name = PP->getSpelling(MacroNameTok);

    llvm::Optional<llvm::StringRef> Replacement = getNewMacroName(Name);
    if (!Replacement)
      return;

    llvm::StringRef FileName = PP->getSourceManager().getFilename(
        MD.getMacroInfo()->getDefinitionLoc());
    if (!FileName.endswith("gtest/gtest-typed-test.h"))
      return;

    DiagnosticBuilder Diag = Check->diag(Loc, RenameCaseToSuiteMessage);

    if (Action == CheckAction::Rename)
      Diag << FixItHint::CreateReplacement(
          CharSourceRange::getTokenRange(Loc, Loc), *Replacement);
  }

  bool ReplacementFound;
  UpgradeGoogletestCaseCheck *Check;
  Preprocessor *PP;
};

} // namespace

void UpgradeGoogletestCaseCheck::registerPPCallbacks(const SourceManager &,
                                                     Preprocessor *PP,
                                                     Preprocessor *) {
  PP->addPPCallbacks(
      std::make_unique<UpgradeGoogletestCasePPCallback>(this, PP));
}

void UpgradeGoogletestCaseCheck::registerMatchers(MatchFinder *Finder) {
  auto LocationFilter =
      unless(isExpansionInFileMatching("gtest/gtest(-typed-test)?\\.h$"));

  // Matchers for the member functions that are being renamed. In each matched
  // Google Test class, we check for the existence of one new method name. This
  // makes sure the check gives warnings only if the included version of Google
  // Test is recent enough.
  auto Methods =
      cxxMethodDecl(
          anyOf(
              cxxMethodDecl(
                  hasAnyName("SetUpTestCase", "TearDownTestCase"),
                  ofClass(
                      cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
                                        hasName("::testing::Test"),
                                        hasMethod(hasName("SetUpTestSuite")))))
                          .bind("class"))),
              cxxMethodDecl(
                  hasName("test_case_name"),
                  ofClass(
                      cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(
                                        hasName("::testing::TestInfo"),
                                        hasMethod(hasName("test_suite_name")))))
                          .bind("class"))),
              cxxMethodDecl(
                  hasAnyName("OnTestCaseStart", "OnTestCaseEnd"),
                  ofClass(cxxRecordDecl(
                              isSameOrDerivedFrom(cxxRecordDecl(
                                  hasName("::testing::TestEventListener"),
                                  hasMethod(hasName("OnTestSuiteStart")))))
                              .bind("class"))),
              cxxMethodDecl(
                  hasAnyName("current_test_case", "successful_test_case_count",
                             "failed_test_case_count", "total_test_case_count",
                             "test_case_to_run_count", "GetTestCase"),
                  ofClass(cxxRecordDecl(
                              isSameOrDerivedFrom(cxxRecordDecl(
                                  hasName("::testing::UnitTest"),
                                  hasMethod(hasName("current_test_suite")))))
                              .bind("class")))))
          .bind("method");

  Finder->addMatcher(expr(anyOf(callExpr(callee(Methods)).bind("call"),
                                declRefExpr(to(Methods)).bind("ref")),
                          LocationFilter),
                     this);

  Finder->addMatcher(
      usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(Methods)), LocationFilter)
          .bind("using"),
      this);

  Finder->addMatcher(cxxMethodDecl(Methods, LocationFilter), this);

  // Matchers for `TestCase` -> `TestSuite`. The fact that `TestCase` is an
  // alias and not a class declaration ensures we only match with a recent
  // enough version of Google Test.
  auto TestCaseTypeAlias =
      typeAliasDecl(hasName("::testing::TestCase")).bind("test-case");
  Finder->addMatcher(
      typeLoc(loc(qualType(typedefType(hasDeclaration(TestCaseTypeAlias)))),
              unless(hasAncestor(decl(isImplicit()))), LocationFilter)
          .bind("typeloc"),
      this);
  Finder->addMatcher(
      usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(TestCaseTypeAlias)))
          .bind("using"),
      this);
}

static llvm::StringRef getNewMethodName(llvm::StringRef CurrentName) {
  std::pair<llvm::StringRef, llvm::StringRef> ReplacementMap[] = {
      {"SetUpTestCase", "SetUpTestSuite"},
      {"TearDownTestCase", "TearDownTestSuite"},
      {"test_case_name", "test_suite_name"},
      {"OnTestCaseStart", "OnTestSuiteStart"},
      {"OnTestCaseEnd", "OnTestSuiteEnd"},
      {"current_test_case", "current_test_suite"},
      {"successful_test_case_count", "successful_test_suite_count"},
      {"failed_test_case_count", "failed_test_suite_count"},
      {"total_test_case_count", "total_test_suite_count"},
      {"test_case_to_run_count", "test_suite_to_run_count"},
      {"GetTestCase", "GetTestSuite"}};

  for (auto &Mapping : ReplacementMap) {
    if (CurrentName == Mapping.first)
      return Mapping.second;
  }

  llvm_unreachable("Unexpected function name");
}

template <typename NodeType>
static bool isInInstantiation(const NodeType &Node,
                              const MatchFinder::MatchResult &Result) {
  return !match(isInTemplateInstantiation(), Node, *Result.Context).empty();
}

template <typename NodeType>
static bool isInTemplate(const NodeType &Node,
                         const MatchFinder::MatchResult &Result) {
  internal::Matcher<NodeType> IsInsideTemplate =
      hasAncestor(decl(anyOf(classTemplateDecl(), functionTemplateDecl())));
  return !match(IsInsideTemplate, Node, *Result.Context).empty();
}

static bool
derivedTypeHasReplacementMethod(const MatchFinder::MatchResult &Result,
                                llvm::StringRef ReplacementMethod) {
  const auto *Class = Result.Nodes.getNodeAs<CXXRecordDecl>("class");
  return !match(cxxRecordDecl(
                    unless(isExpansionInFileMatching(
                        "gtest/gtest(-typed-test)?\\.h$")),
                    hasMethod(cxxMethodDecl(hasName(ReplacementMethod)))),
                *Class, *Result.Context)
              .empty();
}

static CharSourceRange
getAliasNameRange(const MatchFinder::MatchResult &Result) {
  if (const auto *Using = Result.Nodes.getNodeAs<UsingDecl>("using")) {
    return CharSourceRange::getTokenRange(
        Using->getNameInfo().getSourceRange());
  }
  return CharSourceRange::getTokenRange(
      Result.Nodes.getNodeAs<TypeLoc>("typeloc")->getSourceRange());
}

void UpgradeGoogletestCaseCheck::check(const MatchFinder::MatchResult &Result) {
  llvm::StringRef ReplacementText;
  CharSourceRange ReplacementRange;
  if (const auto *Method = Result.Nodes.getNodeAs<CXXMethodDecl>("method")) {
    ReplacementText = getNewMethodName(Method->getName());

    bool IsInInstantiation;
    bool IsInTemplate;
    bool AddFix = true;
    if (const auto *Call = Result.Nodes.getNodeAs<CXXMemberCallExpr>("call")) {
      const auto *Callee = llvm::cast<MemberExpr>(Call->getCallee());
      ReplacementRange = CharSourceRange::getTokenRange(Callee->getMemberLoc(),
                                                        Callee->getMemberLoc());
      IsInInstantiation = isInInstantiation(*Call, Result);
      IsInTemplate = isInTemplate<Stmt>(*Call, Result);
    } else if (const auto *Ref = Result.Nodes.getNodeAs<DeclRefExpr>("ref")) {
      ReplacementRange =
          CharSourceRange::getTokenRange(Ref->getNameInfo().getSourceRange());
      IsInInstantiation = isInInstantiation(*Ref, Result);
      IsInTemplate = isInTemplate<Stmt>(*Ref, Result);
    } else if (const auto *Using = Result.Nodes.getNodeAs<UsingDecl>("using")) {
      ReplacementRange =
          CharSourceRange::getTokenRange(Using->getNameInfo().getSourceRange());
      IsInInstantiation = isInInstantiation(*Using, Result);
      IsInTemplate = isInTemplate<Decl>(*Using, Result);
    } else {
      // This branch means we have matched a function declaration / definition
      // either for a function from googletest or for a function in a derived
      // class.

      ReplacementRange = CharSourceRange::getTokenRange(
          Method->getNameInfo().getSourceRange());
      IsInInstantiation = isInInstantiation(*Method, Result);
      IsInTemplate = isInTemplate<Decl>(*Method, Result);

      // If the type of the matched method is strictly derived from a googletest
      // type and has both the old and new member function names, then we cannot
      // safely rename (or delete) the old name version.
      AddFix = !derivedTypeHasReplacementMethod(Result, ReplacementText);
    }

    if (IsInInstantiation) {
      if (MatchedTemplateLocations.count(ReplacementRange.getBegin()) == 0) {
        // For each location matched in a template instantiation, we check if
        // the location can also be found in `MatchedTemplateLocations`. If it
        // is not found, that means the expression did not create a match
        // without the instantiation and depends on template parameters. A
        // manual fix is probably required so we provide only a warning.
        diag(ReplacementRange.getBegin(), RenameCaseToSuiteMessage);
      }
      return;
    }

    if (IsInTemplate) {
      // We gather source locations from template matches not in template
      // instantiations for future matches.
      MatchedTemplateLocations.insert(ReplacementRange.getBegin());
    }

    if (!AddFix) {
      diag(ReplacementRange.getBegin(), RenameCaseToSuiteMessage);
      return;
    }
  } else {
    // This is a match for `TestCase` to `TestSuite` refactoring.
    assert(Result.Nodes.getNodeAs<TypeAliasDecl>("test-case") != nullptr);
    ReplacementText = "TestSuite";
    ReplacementRange = getAliasNameRange(Result);

    // We do not need to keep track of template instantiations for this branch,
    // because we are matching a `TypeLoc` for the alias declaration. Templates
    // will only be instantiated with the true type name, `TestSuite`.
  }

  DiagnosticBuilder Diag =
      diag(ReplacementRange.getBegin(), RenameCaseToSuiteMessage);

  ReplacementRange = Lexer::makeFileCharRange(
      ReplacementRange, *Result.SourceManager, Result.Context->getLangOpts());
  if (ReplacementRange.isInvalid())
    // An invalid source range likely means we are inside a macro body. A manual
    // fix is likely needed so we do not create a fix-it hint.
    return;

  Diag << FixItHint::CreateReplacement(ReplacementRange, ReplacementText);
}

} // namespace google
} // namespace tidy
} // namespace clang
