//===--- RedundantSmartptrGetCheck.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 "RedundantSmartptrGetCheck.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"

using namespace clang::ast_matchers;

namespace clang::tidy::readability {

namespace {
internal::Matcher<Expr> callToGet(const internal::Matcher<Decl> &OnClass) {
  return expr(
             anyOf(cxxMemberCallExpr(
                       on(expr(anyOf(hasType(OnClass),
                                     hasType(qualType(pointsTo(
                                         decl(OnClass).bind("ptr_to_ptr"))))))
                              .bind("smart_pointer")),
                       unless(callee(
                           memberExpr(hasObjectExpression(cxxThisExpr())))),
                       callee(cxxMethodDecl(hasName("get"),
                                            returns(qualType(pointsTo(
                                                type().bind("getType"))))))),
                   cxxDependentScopeMemberExpr(
                       hasMemberName("get"),
                       hasObjectExpression(
                           expr(hasType(qualType(hasCanonicalType(
                                    templateSpecializationType(hasDeclaration(
                                        classTemplateDecl(has(cxxRecordDecl(
                                            OnClass,
                                            hasMethod(cxxMethodDecl(
                                                hasName("get"),
                                                returns(qualType(
                                                    pointsTo(type().bind(
                                                        "getType")))))))))))))))
                               .bind("smart_pointer")))))
      .bind("redundant_get");
}

internal::Matcher<Decl> knownSmartptr() {
  return recordDecl(hasAnyName("::std::unique_ptr", "::std::shared_ptr"));
}

void registerMatchersForGetArrowStart(MatchFinder *Finder,
                                      MatchFinder::MatchCallback *Callback) {
  const auto QuacksLikeASmartptr = recordDecl(
      recordDecl().bind("duck_typing"),
      has(cxxMethodDecl(hasName("operator->"),
                        returns(qualType(pointsTo(type().bind("op->Type")))))),
      has(cxxMethodDecl(hasName("operator*"), returns(qualType(references(
                                                  type().bind("op*Type")))))));

  // Make sure we are not missing the known standard types.
  const auto Smartptr = anyOf(knownSmartptr(), QuacksLikeASmartptr);

  // Catch 'ptr.get()->Foo()'
  Finder->addMatcher(memberExpr(expr().bind("memberExpr"), isArrow(),
                                hasObjectExpression(callToGet(Smartptr))),
                     Callback);

  // Catch '*ptr.get()' or '*ptr->get()'
  Finder->addMatcher(
      unaryOperator(hasOperatorName("*"), hasUnaryOperand(callToGet(Smartptr))),
      Callback);

  // Catch '!ptr.get()'
  const auto CallToGetAsBool = callToGet(
      recordDecl(Smartptr, has(cxxConversionDecl(returns(booleanType())))));
  Finder->addMatcher(
      unaryOperator(hasOperatorName("!"), hasUnaryOperand(CallToGetAsBool)),
      Callback);

  // Catch 'if(ptr.get())'
  Finder->addMatcher(ifStmt(hasCondition(CallToGetAsBool)), Callback);

  // Catch 'ptr.get() ? X : Y'
  Finder->addMatcher(conditionalOperator(hasCondition(CallToGetAsBool)),
                     Callback);

  Finder->addMatcher(cxxDependentScopeMemberExpr(hasObjectExpression(
                         callExpr(has(callToGet(Smartptr))).bind("obj"))),
                     Callback);
}

void registerMatchersForGetEquals(MatchFinder *Finder,
                                  MatchFinder::MatchCallback *Callback) {
  // This one is harder to do with duck typing.
  // The operator==/!= that we are looking for might be member or non-member,
  // might be on global namespace or found by ADL, might be a template, etc.
  // For now, lets keep it to the known standard types.

  // Matches against nullptr.
  Finder->addMatcher(
      binaryOperator(hasAnyOperatorName("==", "!="),
                     hasOperands(anyOf(cxxNullPtrLiteralExpr(), gnuNullExpr(),
                                       integerLiteral(equals(0))),
                                 callToGet(knownSmartptr()))),
      Callback);

  // FIXME: Match and fix if (l.get() == r.get()).
}

} // namespace

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

void RedundantSmartptrGetCheck::registerMatchers(MatchFinder *Finder) {
  registerMatchersForGetArrowStart(Finder, this);
  registerMatchersForGetEquals(Finder, this);
}

namespace {
bool allReturnTypesMatch(const MatchFinder::MatchResult &Result) {
  if (Result.Nodes.getNodeAs<Decl>("duck_typing") == nullptr)
    return true;
  // Verify that the types match.
  // We can't do this on the matcher because the type nodes can be different,
  // even though they represent the same type. This difference comes from how
  // the type is referenced (eg. through a typedef, a type trait, etc).
  const Type *OpArrowType =
      Result.Nodes.getNodeAs<Type>("op->Type")->getUnqualifiedDesugaredType();
  const Type *OpStarType =
      Result.Nodes.getNodeAs<Type>("op*Type")->getUnqualifiedDesugaredType();
  const Type *GetType =
      Result.Nodes.getNodeAs<Type>("getType")->getUnqualifiedDesugaredType();
  return OpArrowType == OpStarType && OpArrowType == GetType;
}
} // namespace

void RedundantSmartptrGetCheck::check(const MatchFinder::MatchResult &Result) {
  if (!allReturnTypesMatch(Result))
    return;

  bool IsPtrToPtr = Result.Nodes.getNodeAs<Decl>("ptr_to_ptr") != nullptr;
  bool IsMemberExpr = Result.Nodes.getNodeAs<Expr>("memberExpr") != nullptr;
  const auto *GetCall = Result.Nodes.getNodeAs<Expr>("redundant_get");
  if (GetCall->getBeginLoc().isMacroID() && IgnoreMacros)
    return;

  const auto *Smartptr = Result.Nodes.getNodeAs<Expr>("smart_pointer");

  if (IsPtrToPtr && IsMemberExpr) {
    // Ignore this case (eg. Foo->get()->DoSomething());
    return;
  }

  auto SR = GetCall->getSourceRange();
  // CXXDependentScopeMemberExpr source range does not include parens
  // Extend the source range of the get call to account for them.
  if (isa<CXXDependentScopeMemberExpr>(GetCall))
    SR.setEnd(Lexer::getLocForEndOfToken(SR.getEnd(), 0, *Result.SourceManager,
                                         getLangOpts())
                  .getLocWithOffset(1));

  StringRef SmartptrText = Lexer::getSourceText(
      CharSourceRange::getTokenRange(Smartptr->getSourceRange()),
      *Result.SourceManager, getLangOpts());
  // Check if the last two characters are "->" and remove them
  if (SmartptrText.ends_with("->")) {
    SmartptrText = SmartptrText.drop_back(2);
  }
  // Replace foo->get() with *foo, and foo.get() with foo.
  std::string Replacement = Twine(IsPtrToPtr ? "*" : "", SmartptrText).str();
  diag(GetCall->getBeginLoc(), "redundant get() call on smart pointer")
      << FixItHint::CreateReplacement(SR, Replacement);
}

} // namespace clang::tidy::readability
