//===- RedundantStringInitCheck.cpp - clang-tidy ----------------*- C++ -*-===//
//
// 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 "RedundantStringInitCheck.h"
#include "../utils/Matchers.h"
#include "../utils/OptionsUtils.h"
#include "clang/ASTMatchers/ASTMatchers.h"

using namespace clang::ast_matchers;
using namespace clang::tidy::matchers;

namespace clang {
namespace tidy {
namespace readability {

const char DefaultStringNames[] =
    "::std::basic_string_view;::std::basic_string";

static ast_matchers::internal::Matcher<NamedDecl>
hasAnyNameStdString(std::vector<std::string> Names) {
  return ast_matchers::internal::Matcher<NamedDecl>(
      new ast_matchers::internal::HasNameMatcher(std::move(Names)));
}

static std::vector<std::string>
removeNamespaces(const std::vector<std::string> &Names) {
  std::vector<std::string> Result;
  Result.reserve(Names.size());
  for (const std::string &Name : Names) {
    std::string::size_type ColonPos = Name.rfind(':');
    Result.push_back(
        Name.substr(ColonPos == std::string::npos ? 0 : ColonPos + 1));
  }
  return Result;
}

static const CXXConstructExpr *
getConstructExpr(const CXXCtorInitializer &CtorInit) {
  const Expr *InitExpr = CtorInit.getInit();
  if (const auto *CleanUpExpr = dyn_cast<ExprWithCleanups>(InitExpr))
    InitExpr = CleanUpExpr->getSubExpr();
  return dyn_cast<CXXConstructExpr>(InitExpr);
}

static llvm::Optional<SourceRange>
getConstructExprArgRange(const CXXConstructExpr &Construct) {
  SourceLocation B, E;
  for (const Expr *Arg : Construct.arguments()) {
    if (B.isInvalid())
      B = Arg->getBeginLoc();
    if (Arg->getEndLoc().isValid())
      E = Arg->getEndLoc();
  }
  if (B.isInvalid() || E.isInvalid())
    return llvm::None;
  return SourceRange(B, E);
}

RedundantStringInitCheck::RedundantStringInitCheck(StringRef Name,
                                                   ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      StringNames(utils::options::parseStringList(
          Options.get("StringNames", DefaultStringNames))) {}

void RedundantStringInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "StringNames", DefaultStringNames);
}

void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
  const auto hasStringTypeName = hasAnyNameStdString(StringNames);
  const auto hasStringCtorName =
      hasAnyNameStdString(removeNamespaces(StringNames));

  // Match string constructor.
  const auto StringConstructorExpr = expr(
      anyOf(cxxConstructExpr(argumentCountIs(1),
                             hasDeclaration(cxxMethodDecl(hasStringCtorName))),
            // If present, the second argument is the alloc object which must
            // not be present explicitly.
            cxxConstructExpr(argumentCountIs(2),
                             hasDeclaration(cxxMethodDecl(hasStringCtorName)),
                             hasArgument(1, cxxDefaultArgExpr()))));

  // Match a string constructor expression with an empty string literal.
  const auto EmptyStringCtorExpr = cxxConstructExpr(
      StringConstructorExpr,
      hasArgument(0, ignoringParenImpCasts(stringLiteral(hasSize(0)))));

  const auto EmptyStringCtorExprWithTemporaries =
      cxxConstructExpr(StringConstructorExpr,
                       hasArgument(0, ignoringImplicit(EmptyStringCtorExpr)));

  const auto StringType = hasType(hasUnqualifiedDesugaredType(
      recordType(hasDeclaration(cxxRecordDecl(hasStringTypeName)))));
  const auto EmptyStringInit =
      traverse(ast_type_traits::TK_AsIs, expr(ignoringImplicit(
      anyOf(EmptyStringCtorExpr, EmptyStringCtorExprWithTemporaries))));

  // Match a variable declaration with an empty string literal as initializer.
  // Examples:
  //     string foo = "";
  //     string bar("");
  Finder->addMatcher(
      traverse(ast_type_traits::TK_AsIs,
               namedDecl(varDecl(StringType, hasInitializer(EmptyStringInit))
                             .bind("vardecl"),
                         unless(parmVarDecl()))),
      this);
  // Match a field declaration with an empty string literal as initializer.
  Finder->addMatcher(
      namedDecl(fieldDecl(StringType, hasInClassInitializer(EmptyStringInit))
                    .bind("fieldDecl")),
      this);
  // Matches Constructor Initializers with an empty string literal as
  // initializer.
  // Examples:
  //     Foo() : SomeString("") {}
  Finder->addMatcher(
      cxxCtorInitializer(
          isWritten(),
          forField(allOf(StringType, optionally(hasInClassInitializer(
                                         EmptyStringInit.bind("empty_init"))))),
          withInitializer(EmptyStringInit))
          .bind("ctorInit"),
      this);
}

void RedundantStringInitCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *VDecl = Result.Nodes.getNodeAs<VarDecl>("vardecl")) {
    // VarDecl's getSourceRange() spans 'string foo = ""' or 'string bar("")'.
    // So start at getLocation() to span just 'foo = ""' or 'bar("")'.
    SourceRange ReplaceRange(VDecl->getLocation(), VDecl->getEndLoc());
    diag(VDecl->getLocation(), "redundant string initialization")
        << FixItHint::CreateReplacement(ReplaceRange, VDecl->getName());
  }
  if (const auto *FDecl = Result.Nodes.getNodeAs<FieldDecl>("fieldDecl")) {
    // FieldDecl's getSourceRange() spans 'string foo = ""'.
    // So start at getLocation() to span just 'foo = ""'.
    SourceRange ReplaceRange(FDecl->getLocation(), FDecl->getEndLoc());
    diag(FDecl->getLocation(), "redundant string initialization")
        << FixItHint::CreateReplacement(ReplaceRange, FDecl->getName());
  }
  if (const auto *CtorInit =
          Result.Nodes.getNodeAs<CXXCtorInitializer>("ctorInit")) {
    if (const FieldDecl *Member = CtorInit->getMember()) {
      if (!Member->hasInClassInitializer() ||
          Result.Nodes.getNodeAs<Expr>("empty_init")) {
        // The String isn't declared in the class with an initializer or its
        // declared with a redundant initializer, which will be removed. Either
        // way the string will be default initialized, therefore we can remove
        // the constructor initializer entirely.
        diag(CtorInit->getMemberLocation(), "redundant string initialization")
            << FixItHint::CreateRemoval(CtorInit->getSourceRange());
        return;
      }
    }
    const CXXConstructExpr *Construct = getConstructExpr(*CtorInit);
    if (!Construct)
      return;
    if (llvm::Optional<SourceRange> RemovalRange =
            getConstructExprArgRange(*Construct))
      diag(CtorInit->getMemberLocation(), "redundant string initialization")
          << FixItHint::CreateRemoval(*RemovalRange);
  }
}

} // namespace readability
} // namespace tidy
} // namespace clang
