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

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace modernize {

static const char PointerType[] = "pointerType";
static const char ConstructorCall[] = "constructorCall";
static const char NewExpression[] = "newExpression";

void MakeUniqueCheck::registerMatchers(MatchFinder *Finder) {
  if (getLangOpts().CPlusPlus11) {
    Finder->addMatcher(
        cxxBindTemporaryExpr(has(
            cxxConstructExpr(
                hasType(qualType(hasDeclaration(classTemplateSpecializationDecl(
                    matchesName("::std::unique_ptr"),
                    templateArgumentCountIs(2),
                    hasTemplateArgument(0, templateArgument(refersToType(
                                               qualType().bind(PointerType)))),
                    hasTemplateArgument(
                        1, templateArgument(refersToType(qualType(
                               hasDeclaration(classTemplateSpecializationDecl(
                                   matchesName("::std::default_delete"),
                                   templateArgumentCountIs(1),
                                   hasTemplateArgument(
                                       0, templateArgument(refersToType(
                                              qualType(equalsBoundNode(
                                                  PointerType))))))))))))))),
                argumentCountIs(1),
                hasArgument(
                    0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
                                      equalsBoundNode(PointerType))))))
                           .bind(NewExpression)))
                .bind(ConstructorCall))),
        this);
  }
}

void MakeUniqueCheck::check(const MatchFinder::MatchResult &Result) {
  SourceManager &SM = *Result.SourceManager;
  const auto *Construct =
      Result.Nodes.getNodeAs<CXXConstructExpr>(ConstructorCall);
  const auto *Type = Result.Nodes.getNodeAs<QualType>(PointerType);
  const auto *New = Result.Nodes.getNodeAs<CXXNewExpr>(NewExpression);

  if (New->getNumPlacementArgs() != 0)
    return;

  SourceLocation ConstructCallStart = Construct->getExprLoc();

  bool Invalid = false;
  StringRef ExprStr = Lexer::getSourceText(
      CharSourceRange::getCharRange(
          ConstructCallStart, Construct->getParenOrBraceRange().getBegin()),
      SM, LangOptions(), &Invalid);
  if (Invalid)
    return;

  auto Diag = diag(ConstructCallStart, "use std::make_unique instead");

  // Find the location of the template's left angle.
  size_t LAngle = ExprStr.find("<");
  SourceLocation ConstructCallEnd;
  if (LAngle == StringRef::npos) {
    // If the template argument is missing (because it is part of the alias)
    // we have to add it back.
    ConstructCallEnd = ConstructCallStart.getLocWithOffset(ExprStr.size());
    Diag << FixItHint::CreateInsertion(
        ConstructCallEnd, "<" + Type->getAsString(getLangOpts()) + ">");
  } else {
    ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle);
  }

  Diag << FixItHint::CreateReplacement(
      CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd),
      "std::make_unique");

  // If the unique_ptr is built with brace enclosed direct initialization, use
  // parenthesis instead.
  if (Construct->isListInitialization()) {
    SourceRange BraceRange = Construct->getParenOrBraceRange();
    Diag << FixItHint::CreateReplacement(
        CharSourceRange::getCharRange(
            BraceRange.getBegin(), BraceRange.getBegin().getLocWithOffset(1)),
        "(");
    Diag << FixItHint::CreateReplacement(
        CharSourceRange::getCharRange(BraceRange.getEnd(),
                                      BraceRange.getEnd().getLocWithOffset(1)),
        ")");
  }

  SourceLocation NewStart = New->getSourceRange().getBegin();
  SourceLocation NewEnd = New->getSourceRange().getEnd();
  switch (New->getInitializationStyle()) {
  case CXXNewExpr::NoInit: {
    Diag << FixItHint::CreateRemoval(SourceRange(NewStart, NewEnd));
    break;
  }
  case CXXNewExpr::CallInit: {
    SourceRange InitRange = New->getDirectInitRange();
    Diag << FixItHint::CreateRemoval(
        SourceRange(NewStart, InitRange.getBegin()));
    Diag << FixItHint::CreateRemoval(SourceRange(InitRange.getEnd(), NewEnd));
    break;
  }
  case CXXNewExpr::ListInit: {
    // Range of the substring that we do not want to remove.
    SourceRange InitRange;
    if (const auto *NewConstruct = New->getConstructExpr()) {
      // Direct initialization with initialization list.
      //   struct S { S(int x) {} };
      //   std::unique_ptr<S>(new S{5});
      // The arguments in the initialization list are going to be forwarded to
      // the constructor, so this has to be replaced with:
      //   struct S { S(int x) {} };
      //   std::make_unique<S>(5);
      InitRange = SourceRange(
          NewConstruct->getParenOrBraceRange().getBegin().getLocWithOffset(1),
          NewConstruct->getParenOrBraceRange().getEnd().getLocWithOffset(-1));
    } else {
      // Aggregate initialization.
      //   std::unique_ptr<Pair>(new Pair{first, second});
      // Has to be replaced with:
      //   std::make_unique<Pair>(Pair{first, second});
      InitRange = SourceRange(
          New->getAllocatedTypeSourceInfo()->getTypeLoc().getLocStart(),
          New->getInitializer()->getSourceRange().getEnd());
    }
    Diag << FixItHint::CreateRemoval(
        CharSourceRange::getCharRange(NewStart, InitRange.getBegin()));
    Diag << FixItHint::CreateRemoval(
        SourceRange(InitRange.getEnd().getLocWithOffset(1), NewEnd));
    break;
  }
  }
}

} // namespace modernize
} // namespace tidy
} // namespace clang
