//===--- AvoidNSObjectNewCheck.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 "AvoidNSObjectNewCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/Support/FormatVariadic.h"
#include <map>
#include <string>

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace google {
namespace objc {

static bool isMessageExpressionInsideMacro(const ObjCMessageExpr *Expr) {
  SourceLocation ReceiverLocation = Expr->getReceiverRange().getBegin();
  if (ReceiverLocation.isMacroID())
    return true;

  SourceLocation SelectorLocation = Expr->getSelectorStartLoc();
  if (SelectorLocation.isMacroID())
    return true;

  return false;
}

// Walk up the class hierarchy looking for an -init method, returning true
// if one is found and has not been marked unavailable.
static bool isInitMethodAvailable(const ObjCInterfaceDecl *ClassDecl) {
  while (ClassDecl != nullptr) {
    for (const auto *MethodDecl : ClassDecl->instance_methods()) {
      if (MethodDecl->getSelector().getAsString() == "init")
        return !MethodDecl->isUnavailable();
    }
    ClassDecl = ClassDecl->getSuperClass();
  }

  // No -init method found in the class hierarchy. This should occur only rarely
  // in Objective-C code, and only really applies to classes not derived from
  // NSObject.
  return false;
}

// Returns the string for the Objective-C message receiver. Keeps any generics
// included in the receiver class type, which are stripped if the class type is
// used. While the generics arguments will not make any difference to the
// returned code at this time, the style guide allows them and they should be
// left in any fix-it hint.
static StringRef getReceiverString(SourceRange ReceiverRange,
                                   const SourceManager &SM,
                                   const LangOptions &LangOpts) {
  CharSourceRange CharRange = Lexer::makeFileCharRange(
      CharSourceRange::getTokenRange(ReceiverRange), SM, LangOpts);
  return Lexer::getSourceText(CharRange, SM, LangOpts);
}

static FixItHint getCallFixItHint(const ObjCMessageExpr *Expr,
                                  const SourceManager &SM,
                                  const LangOptions &LangOpts) {
  // Check whether the messaged class has a known factory method to use instead
  // of -init.
  StringRef Receiver =
      getReceiverString(Expr->getReceiverRange(), SM, LangOpts);
  // Some classes should use standard factory methods instead of alloc/init.
  std::map<StringRef, StringRef> ClassToFactoryMethodMap = {{"NSDate", "date"},
                                                            {"NSNull", "null"}};
  auto FoundClassFactory = ClassToFactoryMethodMap.find(Receiver);
  if (FoundClassFactory != ClassToFactoryMethodMap.end()) {
    StringRef ClassName = FoundClassFactory->first;
    StringRef FactorySelector = FoundClassFactory->second;
    std::string NewCall =
        std::string(llvm::formatv("[{0} {1}]", ClassName, FactorySelector));
    return FixItHint::CreateReplacement(Expr->getSourceRange(), NewCall);
  }

  if (isInitMethodAvailable(Expr->getReceiverInterface())) {
    std::string NewCall =
        std::string(llvm::formatv("[[{0} alloc] init]", Receiver));
    return FixItHint::CreateReplacement(Expr->getSourceRange(), NewCall);
  }

  return {}; // No known replacement available.
}

void AvoidNSObjectNewCheck::registerMatchers(MatchFinder *Finder) {
  // Add two matchers, to catch calls to +new and implementations of +new.
  Finder->addMatcher(
      objcMessageExpr(isClassMessage(), hasSelector("new")).bind("new_call"),
      this);
  Finder->addMatcher(
      objcMethodDecl(isClassMethod(), isDefinition(), hasName("new"))
          .bind("new_override"),
      this);
}

void AvoidNSObjectNewCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *CallExpr =
          Result.Nodes.getNodeAs<ObjCMessageExpr>("new_call")) {
    // Don't warn if the call expression originates from a macro expansion.
    if (isMessageExpressionInsideMacro(CallExpr))
      return;

    diag(CallExpr->getExprLoc(), "do not create objects with +new")
        << getCallFixItHint(CallExpr, *Result.SourceManager,
                            Result.Context->getLangOpts());
  }

  if (const auto *DeclExpr =
          Result.Nodes.getNodeAs<ObjCMethodDecl>("new_override")) {
    diag(DeclExpr->getBeginLoc(), "classes should not override +new");
  }
}

} // namespace objc
} // namespace google
} // namespace tidy
} // namespace clang
