//===--- IsolateDeclarationCheck.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 "IsolateDeclarationCheck.h"
#include "../utils/LexerUtils.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include <optional>

using namespace clang::ast_matchers;
using namespace clang::tidy::utils::lexer;

namespace clang::tidy::readability {

namespace {
AST_MATCHER(DeclStmt, isSingleDecl) { return Node.isSingleDecl(); }
AST_MATCHER(DeclStmt, onlyDeclaresVariables) {
  return llvm::all_of(Node.decls(), [](Decl *D) { return isa<VarDecl>(D); });
}
} // namespace

void IsolateDeclarationCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(declStmt(onlyDeclaresVariables(), unless(isSingleDecl()),
                              hasParent(compoundStmt()))
                         .bind("decl_stmt"),
                     this);
}

static SourceLocation findStartOfIndirection(SourceLocation Start,
                                             int Indirections,
                                             const SourceManager &SM,
                                             const LangOptions &LangOpts) {
  assert(Indirections >= 0 && "Indirections must be non-negative");
  if (Indirections == 0)
    return Start;

  // Note that the post-fix decrement is necessary to perform the correct
  // number of transformations.
  while (Indirections-- != 0) {
    Start = findPreviousAnyTokenKind(Start, SM, LangOpts, tok::star, tok::amp);
    if (Start.isInvalid() || Start.isMacroID())
      return SourceLocation();
  }
  return Start;
}

static bool isMacroID(SourceRange R) {
  return R.getBegin().isMacroID() || R.getEnd().isMacroID();
}

/// This function counts the number of written indirections for the given
/// Type \p T. It does \b NOT resolve typedefs as it's a helper for lexing
/// the source code.
/// \see declRanges
static int countIndirections(const Type *T, int Indirections = 0) {
  if (T->isFunctionPointerType()) {
    const auto *Pointee = T->getPointeeType()->castAs<FunctionType>();
    return countIndirections(
        Pointee->getReturnType().IgnoreParens().getTypePtr(), ++Indirections);
  }

  // Note: Do not increment the 'Indirections' because it is not yet clear
  // if there is an indirection added in the source code of the array
  // declaration.
  if (const auto *AT = dyn_cast<ArrayType>(T))
    return countIndirections(AT->getElementType().IgnoreParens().getTypePtr(),
                             Indirections);

  if (isa<PointerType>(T) || isa<ReferenceType>(T))
    return countIndirections(T->getPointeeType().IgnoreParens().getTypePtr(),
                             ++Indirections);

  return Indirections;
}

static bool typeIsMemberPointer(const Type *T) {
  if (isa<ArrayType>(T))
    return typeIsMemberPointer(T->getArrayElementTypeNoTypeQual());

  if ((isa<PointerType>(T) || isa<ReferenceType>(T)) &&
      isa<PointerType>(T->getPointeeType()))
    return typeIsMemberPointer(T->getPointeeType().getTypePtr());

  return isa<MemberPointerType>(T);
}

/// This function tries to extract the SourceRanges that make up all
/// declarations in this \c DeclStmt.
///
/// The resulting vector has the structure {UnderlyingType, Decl1, Decl2, ...}.
/// Each \c SourceRange is of the form [Begin, End).
/// If any of the create ranges is invalid or in a macro the result will be
/// \c None.
/// If the \c DeclStmt contains only one declaration, the result is \c None.
/// If the \c DeclStmt contains declarations other than \c VarDecl the result
/// is \c None.
///
/// \code
///    int * ptr1 = nullptr, value = 42;
/// // [  ][              ] [         ] - The ranges here are inclusive
/// \endcode
/// \todo Generalize this function to take other declarations than \c VarDecl.
static std::optional<std::vector<SourceRange>>
declRanges(const DeclStmt *DS, const SourceManager &SM,
           const LangOptions &LangOpts) {
  std::size_t DeclCount = std::distance(DS->decl_begin(), DS->decl_end());
  if (DeclCount < 2)
    return std::nullopt;

  if (rangeContainsExpansionsOrDirectives(DS->getSourceRange(), SM, LangOpts))
    return std::nullopt;

  // The initial type of the declaration and each declaration has it's own
  // slice. This is necessary, because pointers and references bind only
  // to the local variable and not to all variables in the declaration.
  // Example: 'int *pointer, value = 42;'
  std::vector<SourceRange> Slices;
  Slices.reserve(DeclCount + 1);

  // Calculate the first slice, for now only variables are handled but in the
  // future this should be relaxed and support various kinds of declarations.
  const auto *FirstDecl = dyn_cast<VarDecl>(*DS->decl_begin());

  if (FirstDecl == nullptr)
    return std::nullopt;

  // FIXME: Member pointers are not transformed correctly right now, that's
  // why they are treated as problematic here.
  if (typeIsMemberPointer(FirstDecl->getType().IgnoreParens().getTypePtr()))
    return std::nullopt;

  // Consider the following case: 'int * pointer, value = 42;'
  // Created slices (inclusive)    [  ][       ] [         ]
  // Because 'getBeginLoc' points to the start of the variable *name*, the
  // location of the pointer must be determined separately.
  SourceLocation Start = findStartOfIndirection(
      FirstDecl->getLocation(),
      countIndirections(FirstDecl->getType().IgnoreParens().getTypePtr()), SM,
      LangOpts);

  // Fix function-pointer declarations that have a '(' in front of the
  // pointer.
  // Example: 'void (*f2)(int), (*g2)(int, float) = gg;'
  // Slices:   [   ][        ] [                     ]
  if (FirstDecl->getType()->isFunctionPointerType())
    Start = findPreviousTokenKind(Start, SM, LangOpts, tok::l_paren);

  // It is possible that a declarator is wrapped with parens.
  // Example: 'float (((*f_ptr2)))[42], *f_ptr3, ((f_value2)) = 42.f;'
  // The slice for the type-part must not contain these parens. Consequently
  // 'Start' is moved to the most left paren if there are parens.
  while (true) {
    if (Start.isInvalid() || Start.isMacroID())
      break;

    Token T = getPreviousToken(Start, SM, LangOpts);
    if (T.is(tok::l_paren)) {
      Start = findPreviousTokenStart(Start, SM, LangOpts);
      continue;
    }
    break;
  }

  SourceRange DeclRange(DS->getBeginLoc(), Start);
  if (DeclRange.isInvalid() || isMacroID(DeclRange))
    return std::nullopt;

  // The first slice, that is prepended to every isolated declaration, is
  // created.
  Slices.emplace_back(DeclRange);

  // Create all following slices that each declare a variable.
  SourceLocation DeclBegin = Start;
  for (const auto &Decl : DS->decls()) {
    const auto *CurrentDecl = cast<VarDecl>(Decl);

    // FIXME: Member pointers are not transformed correctly right now, that's
    // why they are treated as problematic here.
    if (typeIsMemberPointer(CurrentDecl->getType().IgnoreParens().getTypePtr()))
      return std::nullopt;

    SourceLocation DeclEnd =
        CurrentDecl->hasInit()
            ? findNextTerminator(CurrentDecl->getInit()->getEndLoc(), SM,
                                 LangOpts)
            : findNextTerminator(CurrentDecl->getEndLoc(), SM, LangOpts);

    SourceRange VarNameRange(DeclBegin, DeclEnd);
    if (VarNameRange.isInvalid() || isMacroID(VarNameRange))
      return std::nullopt;

    Slices.emplace_back(VarNameRange);
    DeclBegin = DeclEnd.getLocWithOffset(1);
  }
  return Slices;
}

static std::optional<std::vector<StringRef>>
collectSourceRanges(llvm::ArrayRef<SourceRange> Ranges, const SourceManager &SM,
                    const LangOptions &LangOpts) {
  std::vector<StringRef> Snippets;
  Snippets.reserve(Ranges.size());

  for (const auto &Range : Ranges) {
    CharSourceRange CharRange = Lexer::getAsCharRange(
        CharSourceRange::getCharRange(Range.getBegin(), Range.getEnd()), SM,
        LangOpts);

    if (CharRange.isInvalid())
      return std::nullopt;

    bool InvalidText = false;
    StringRef Snippet =
        Lexer::getSourceText(CharRange, SM, LangOpts, &InvalidText);

    if (InvalidText)
      return std::nullopt;

    Snippets.emplace_back(Snippet);
  }

  return Snippets;
}

/// Expects a vector {TypeSnippet, Firstdecl, SecondDecl, ...}.
static std::vector<std::string>
createIsolatedDecls(llvm::ArrayRef<StringRef> Snippets) {
  // The first section is the type snippet, which does not make a decl itself.
  assert(Snippets.size() > 2 && "Not enough snippets to create isolated decls");
  std::vector<std::string> Decls(Snippets.size() - 1);

  for (std::size_t I = 1; I < Snippets.size(); ++I)
    Decls[I - 1] = Twine(Snippets[0])
                       .concat(Snippets[0].endswith(" ") ? "" : " ")
                       .concat(Snippets[I].ltrim())
                       .concat(";")
                       .str();

  return Decls;
}

void IsolateDeclarationCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *WholeDecl = Result.Nodes.getNodeAs<DeclStmt>("decl_stmt");

  auto Diag =
      diag(WholeDecl->getBeginLoc(),
           "multiple declarations in a single statement reduces readability");

  std::optional<std::vector<SourceRange>> PotentialRanges =
      declRanges(WholeDecl, *Result.SourceManager, getLangOpts());
  if (!PotentialRanges)
    return;

  std::optional<std::vector<StringRef>> PotentialSnippets = collectSourceRanges(
      *PotentialRanges, *Result.SourceManager, getLangOpts());

  if (!PotentialSnippets)
    return;

  std::vector<std::string> NewDecls = createIsolatedDecls(*PotentialSnippets);
  std::string Replacement = llvm::join(
      NewDecls,
      (Twine("\n") + Lexer::getIndentationForLine(WholeDecl->getBeginLoc(),
                                                  *Result.SourceManager))
          .str());

  Diag << FixItHint::CreateReplacement(WholeDecl->getSourceRange(),
                                       Replacement);
}
} // namespace clang::tidy::readability
