//===--- NSInvocationArgumentLifetimeCheck.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 "NSInvocationArgumentLifetimeCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ComputeDependence.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/StringRef.h"
#include <optional>

using namespace clang::ast_matchers;

namespace clang::tidy::objc {
namespace {

static constexpr StringRef WeakText = "__weak";
static constexpr StringRef StrongText = "__strong";
static constexpr StringRef UnsafeUnretainedText = "__unsafe_unretained";

/// Matches ObjCIvarRefExpr, DeclRefExpr, or MemberExpr that reference
/// Objective-C object (or block) variables or fields whose object lifetimes
/// are not __unsafe_unretained.
AST_POLYMORPHIC_MATCHER(isObjCManagedLifetime,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(ObjCIvarRefExpr,
                                                        DeclRefExpr,
                                                        MemberExpr)) {
  QualType QT = Node.getType();
  return QT->isScalarType() &&
         (QT->getScalarTypeKind() == Type::STK_ObjCObjectPointer ||
          QT->getScalarTypeKind() == Type::STK_BlockPointer) &&
         QT.getQualifiers().getObjCLifetime() > Qualifiers::OCL_ExplicitNone;
}

static std::optional<FixItHint>
fixItHintReplacementForOwnershipString(StringRef Text, CharSourceRange Range,
                                       StringRef Ownership) {
  size_t Index = Text.find(Ownership);
  if (Index == StringRef::npos)
    return std::nullopt;

  SourceLocation Begin = Range.getBegin().getLocWithOffset(Index);
  SourceLocation End = Begin.getLocWithOffset(Ownership.size());
  return FixItHint::CreateReplacement(SourceRange(Begin, End),
                                      UnsafeUnretainedText);
}

static std::optional<FixItHint>
fixItHintForVarDecl(const VarDecl *VD, const SourceManager &SM,
                    const LangOptions &LangOpts) {
  assert(VD && "VarDecl parameter must not be null");
  // Don't provide fix-its for any parameter variables at this time.
  if (isa<ParmVarDecl>(VD))
    return std::nullopt;

  // Currently there is no way to directly get the source range for the
  // __weak/__strong ObjC lifetime qualifiers, so it's necessary to string
  // search in the source code.
  CharSourceRange Range = Lexer::makeFileCharRange(
      CharSourceRange::getTokenRange(VD->getSourceRange()), SM, LangOpts);
  if (Range.isInvalid()) {
    // An invalid range likely means inside a macro, in which case don't supply
    // a fix-it.
    return std::nullopt;
  }

  StringRef VarDeclText = Lexer::getSourceText(Range, SM, LangOpts);
  if (std::optional<FixItHint> Hint =
          fixItHintReplacementForOwnershipString(VarDeclText, Range, WeakText))
    return Hint;

  if (std::optional<FixItHint> Hint = fixItHintReplacementForOwnershipString(
          VarDeclText, Range, StrongText))
    return Hint;

  return FixItHint::CreateInsertion(Range.getBegin(), "__unsafe_unretained ");
}

} // namespace

void NSInvocationArgumentLifetimeCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(
      traverse(
          TK_AsIs,
          objcMessageExpr(
              hasReceiverType(asString("NSInvocation *")),
              anyOf(hasSelector("getArgument:atIndex:"),
                    hasSelector("getReturnValue:")),
              hasArgument(
                  0,
                  anyOf(hasDescendant(memberExpr(isObjCManagedLifetime())),
                        hasDescendant(objcIvarRefExpr(isObjCManagedLifetime())),
                        hasDescendant(
                            // Reference to variables, but when dereferencing
                            // to ivars/fields a more-descendent variable
                            // reference (e.g. self) may match with strong
                            // object lifetime, leading to an incorrect match.
                            // Exclude these conditions.
                            declRefExpr(to(varDecl().bind("var")),
                                        unless(hasParent(implicitCastExpr())),
                                        isObjCManagedLifetime())))))
              .bind("call")),
      this);
}

void NSInvocationArgumentLifetimeCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *MatchedExpr = Result.Nodes.getNodeAs<ObjCMessageExpr>("call");

  auto Diag = diag(MatchedExpr->getArg(0)->getBeginLoc(),
                   "NSInvocation %objcinstance0 should only pass pointers to "
                   "objects with ownership __unsafe_unretained")
              << MatchedExpr->getSelector();

  // Only provide fix-it hints for references to local variables; fixes for
  // instance variable references don't have as clear an automated fix.
  const auto *VD = Result.Nodes.getNodeAs<VarDecl>("var");
  if (!VD)
    return;

  if (auto Hint = fixItHintForVarDecl(VD, *Result.SourceManager,
                                      Result.Context->getLangOpts()))
    Diag << *Hint;
}

} // namespace clang::tidy::objc
