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

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace abseil {

namespace {

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

llvm::Optional<std::string> makeCharacterLiteral(const StringLiteral *Literal,
                                                 const ASTContext &Context) {
  assert(Literal->getLength() == 1 &&
         "Only single character string should be matched");
  assert(Literal->getCharByteWidth() == 1 &&
         "StrSplit doesn't support wide char");
  std::string Result = clang::tooling::fixit::getText(*Literal, Context).str();
  bool IsRawStringLiteral = StringRef(Result).startswith(R"(R")");
  // Since raw string literal might contain unescaped non-printable characters,
  // we normalize them using `StringLiteral::outputString`.
  if (IsRawStringLiteral) {
    Result.clear();
    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"('\'')");

  // Now replace the " with '.
  std::string::size_type 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
  // constructed from string literal.
  auto StringViewArg = ignoringElidableConstructorCall(ignoringImpCasts(
      cxxConstructExpr(hasType(recordDecl(hasName("::absl::string_view"))),
                       hasArgument(0, ignoringParenImpCasts(SingleChar)))));

  // Need to ignore the elidable constructor as otherwise there is no match for
  // c++14 and earlier.
  auto ByAnyCharArg =
      expr(has(ignoringElidableConstructorCall(
               ignoringParenCasts(cxxBindTemporaryExpr(has(cxxConstructExpr(
                   hasType(recordDecl(hasName("::absl::ByAnyChar"))),
                   hasArgument(0, 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, *Result.Context);
  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
