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

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace abseil {

// TODO: Features to add to the check:
//  - Make it work if num_args > 26.
//  - Remove empty literal string arguments.
//  - Collapse consecutive literal string arguments into one (remove the ,).
//  - Replace StrCat(a + b)  ->  StrCat(a, b)  if a or b are strings.
//  - Make it work in macros if the outer and inner StrCats are both in the
//    argument.

void RedundantStrcatCallsCheck::registerMatchers(MatchFinder* Finder) {
  const auto CallToStrcat =
      callExpr(callee(functionDecl(hasName("::absl::StrCat"))));
  const auto CallToStrappend =
      callExpr(callee(functionDecl(hasName("::absl::StrAppend"))));
  // Do not match StrCat() calls that are descendants of other StrCat calls.
  // Those are handled on the ancestor call.
  const auto CallToEither = callExpr(
      callee(functionDecl(hasAnyName("::absl::StrCat", "::absl::StrAppend"))));
  Finder->addMatcher(
      callExpr(CallToStrcat, unless(hasAncestor(CallToEither))).bind("StrCat"),
      this);
  Finder->addMatcher(CallToStrappend.bind("StrAppend"), this);
}

namespace {

struct StrCatCheckResult {
  int NumCalls = 0;
  std::vector<FixItHint> Hints;
};

void removeCallLeaveArgs(const CallExpr *Call, StrCatCheckResult *CheckResult) {
  if (Call->getNumArgs() == 0)
    return;
  // Remove 'Foo('
  CheckResult->Hints.push_back(
      FixItHint::CreateRemoval(CharSourceRange::getCharRange(
          Call->getBeginLoc(), Call->getArg(0)->getBeginLoc())));
  // Remove the ')'
  CheckResult->Hints.push_back(
      FixItHint::CreateRemoval(CharSourceRange::getCharRange(
          Call->getRParenLoc(), Call->getEndLoc().getLocWithOffset(1))));
}

const clang::CallExpr *processArgument(const Expr *Arg,
                                       const MatchFinder::MatchResult &Result,
                                       StrCatCheckResult *CheckResult) {
  const auto IsAlphanum = hasDeclaration(cxxMethodDecl(hasName("AlphaNum")));
  static const auto* const Strcat = new auto(hasName("::absl::StrCat"));
  const auto IsStrcat = cxxBindTemporaryExpr(
      has(callExpr(callee(functionDecl(*Strcat))).bind("StrCat")));
  if (const auto *SubStrcatCall = selectFirst<const CallExpr>(
          "StrCat",
          match(stmt(traverse(TK_AsIs,
                              anyOf(cxxConstructExpr(IsAlphanum,
                                                     hasArgument(0, IsStrcat)),
                                    IsStrcat))),
                *Arg->IgnoreParenImpCasts(), *Result.Context))) {
    removeCallLeaveArgs(SubStrcatCall, CheckResult);
    return SubStrcatCall;
  }
  return nullptr;
}

StrCatCheckResult processCall(const CallExpr *RootCall, bool IsAppend,
                              const MatchFinder::MatchResult &Result) {
  StrCatCheckResult CheckResult;
  std::deque<const CallExpr*> CallsToProcess = {RootCall};

  while (!CallsToProcess.empty()) {
    ++CheckResult.NumCalls;

    const CallExpr* CallExpr = CallsToProcess.front();
    CallsToProcess.pop_front();

    int StartArg = CallExpr == RootCall && IsAppend;
    for (const auto *Arg : CallExpr->arguments()) {
      if (StartArg-- > 0) 
      	continue;
      if (const clang::CallExpr *Sub =
              processArgument(Arg, Result, &CheckResult)) {
        CallsToProcess.push_back(Sub);
      }
    }
  }
  return CheckResult;
}
}  // namespace

void RedundantStrcatCallsCheck::check(const MatchFinder::MatchResult& Result) {
  bool IsAppend;

  const CallExpr* RootCall;
  if ((RootCall = Result.Nodes.getNodeAs<CallExpr>("StrCat"))) 
  	IsAppend = false;
  else if ((RootCall = Result.Nodes.getNodeAs<CallExpr>("StrAppend"))) 
  	IsAppend = true;
  else 
  	return;

  if (RootCall->getBeginLoc().isMacroID()) {
    // Ignore calls within macros.
    // In many cases the outer StrCat part of the macro and the inner StrCat is
    // a macro argument. Removing the inner StrCat() converts one macro
    // argument into many.
    return;
  }

  const StrCatCheckResult CheckResult = processCall(RootCall, IsAppend, Result);
  if (CheckResult.NumCalls == 1) {
    // Just one call, so nothing to fix.
    return;
  }

  diag(RootCall->getBeginLoc(), 
  	   "multiple calls to 'absl::StrCat' can be flattened into a single call")
      << CheckResult.Hints;
}

}  // namespace abseil
}  // namespace tidy
}  // namespace clang
