//===--- ShrinkToFitCheck.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 "ShrinkToFitCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/StringRef.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace modernize {

void ShrinkToFitCheck::registerMatchers(MatchFinder *Finder) {
  // Swap as a function need not to be considered, because rvalue can not
  // be bound to a non-const reference.
  const auto ShrinkableExpr = mapAnyOf(memberExpr, declRefExpr);
  const auto Shrinkable =
      ShrinkableExpr.with(hasDeclaration(valueDecl().bind("ContainerDecl")));
  const auto BoundShrinkable = ShrinkableExpr.with(
      hasDeclaration(valueDecl(equalsBoundNode("ContainerDecl"))));

  Finder->addMatcher(
      cxxMemberCallExpr(
          callee(cxxMethodDecl(hasName("swap"))),
          hasArgument(
              0, anyOf(Shrinkable, unaryOperator(hasUnaryOperand(Shrinkable)))),
          on(cxxConstructExpr(hasArgument(
              0,
              expr(anyOf(BoundShrinkable,
                         unaryOperator(hasUnaryOperand(BoundShrinkable))),
                   hasType(hasCanonicalType(hasDeclaration(namedDecl(hasAnyName(
                       "std::basic_string", "std::deque", "std::vector"))))))
                  .bind("ContainerToShrink")))))
          .bind("CopyAndSwapTrick"),
      this);
}

void ShrinkToFitCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *MemberCall =
      Result.Nodes.getNodeAs<CXXMemberCallExpr>("CopyAndSwapTrick");
  const auto *Container = Result.Nodes.getNodeAs<Expr>("ContainerToShrink");
  FixItHint Hint;

  if (!MemberCall->getBeginLoc().isMacroID()) {
    const LangOptions &Opts = getLangOpts();
    std::string ReplacementText;
    if (const auto *UnaryOp = llvm::dyn_cast<UnaryOperator>(Container)) {
      ReplacementText = std::string(
          Lexer::getSourceText(CharSourceRange::getTokenRange(
                                   UnaryOp->getSubExpr()->getSourceRange()),
                               *Result.SourceManager, Opts));
      ReplacementText += "->shrink_to_fit()";
    } else {
      ReplacementText = std::string(Lexer::getSourceText(
          CharSourceRange::getTokenRange(Container->getSourceRange()),
          *Result.SourceManager, Opts));
      ReplacementText += ".shrink_to_fit()";
    }

    Hint = FixItHint::CreateReplacement(MemberCall->getSourceRange(),
                                        ReplacementText);
  }

  diag(MemberCall->getBeginLoc(), "the shrink_to_fit method should be used "
                                  "to reduce the capacity of a shrinkable "
                                  "container")
      << Hint;
}

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