//===- 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(
      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(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
