//===--- FasterStrsplitDelimiterCheck.cpp - clang-tidy---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "FasterStrsplitDelimiterCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace abseil {

namespace {

AST_MATCHER(StringLiteral, lengthIsOne) { return Node.getLength() == 1; }

::internal::Matcher<Expr>
constructExprWithArg(llvm::StringRef ClassName,
                     const ::internal::Matcher<Expr> &Arg) {
  auto ConstrExpr = cxxConstructExpr(hasType(recordDecl(hasName(ClassName))),
                                     hasArgument(0, ignoringParenCasts(Arg)));

  return anyOf(ConstrExpr, cxxBindTemporaryExpr(has(ConstrExpr)));
}

::internal::Matcher<Expr>
copyConstructExprWithArg(llvm::StringRef ClassName,
                         const ::internal::Matcher<Expr> &Arg) {
  return constructExprWithArg(ClassName, constructExprWithArg(ClassName, Arg));
}

llvm::Optional<std::string> makeCharacterLiteral(const StringLiteral *Literal) {
  std::string Result;
  {
    llvm::raw_string_ostream Stream(Result);
    Literal->outputString(Stream);
  }

  // Special case: If the string contains a single quote, we just need to return
  // a character of the single quote. This is a special case because we need to
  // escape it in the character literal.
  if (Result == R"("'")")
    return std::string(R"('\'')");

  assert(Result.size() == 3 || (Result.size() == 4 && Result.substr(0, 2) == "\"\\"));

  // Now replace the " with '.
  auto Pos = Result.find_first_of('"');
  if (Pos == Result.npos)
    return llvm::None;
  Result[Pos] = '\'';
  Pos = Result.find_last_of('"');
  if (Pos == Result.npos)
    return llvm::None;
  Result[Pos] = '\'';
  return Result;
}

} // anonymous namespace

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

  // Binds to one character string literals.
  const auto SingleChar =
      expr(ignoringParenCasts(stringLiteral(lengthIsOne()).bind("Literal")));

  // Binds to a string_view (either absl or std) that was passed by value and
  // contructed from string literal.
  auto StringViewArg =
      copyConstructExprWithArg("::absl::string_view", SingleChar);

  auto ByAnyCharArg =
      expr(copyConstructExprWithArg("::absl::ByAnyChar", StringViewArg))
          .bind("ByAnyChar");

  // Find uses of absl::StrSplit(..., "x") and absl::StrSplit(...,
  // absl::ByAnyChar("x")) to transform them into absl::StrSplit(..., 'x').
  Finder->addMatcher(callExpr(callee(functionDecl(hasName("::absl::StrSplit"))),
                              hasArgument(1, anyOf(ByAnyCharArg, SingleChar)),
                              unless(isInTemplateInstantiation()))
                         .bind("StrSplit"),
                     this);

  // Find uses of absl::MaxSplits("x", N) and
  // absl::MaxSplits(absl::ByAnyChar("x"), N) to transform them into
  // absl::MaxSplits('x', N).
  Finder->addMatcher(
      callExpr(
          callee(functionDecl(hasName("::absl::MaxSplits"))),
          hasArgument(0, anyOf(ByAnyCharArg, ignoringParenCasts(SingleChar))),
          unless(isInTemplateInstantiation())),
      this);
}

void FasterStrsplitDelimiterCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *Literal = Result.Nodes.getNodeAs<StringLiteral>("Literal");

  if (Literal->getBeginLoc().isMacroID() || Literal->getEndLoc().isMacroID())
    return;

  llvm::Optional<std::string> Replacement = makeCharacterLiteral(Literal);
  if (!Replacement)
    return;
  SourceRange Range = Literal->getSourceRange();

  if (const auto *ByAnyChar = Result.Nodes.getNodeAs<Expr>("ByAnyChar"))
    Range = ByAnyChar->getSourceRange();

  diag(
      Literal->getBeginLoc(),
      "%select{absl::StrSplit()|absl::MaxSplits()}0 called with a string "
      "literal "
      "consisting of a single character; consider using the character overload")
      << (Result.Nodes.getNodeAs<CallExpr>("StrSplit") ? 0 : 1)
      << FixItHint::CreateReplacement(CharSourceRange::getTokenRange(Range),
                                      *Replacement);
}

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