//===--- 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"

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 *) {
  if (!getLangOpts().CPlusPlus)
    return;

  PP->addPPCallbacks(
      std::make_unique<UpgradeGoogletestCasePPCallback>(this, PP));
}

void UpgradeGoogletestCaseCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;

  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().getRawEncoding()) == 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().getRawEncoding());
    }

    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
