//===--- UseAnyOfAllOfCheck.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 "UseAnyOfAllOfCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
#include "clang/Frontend/CompilerInstance.h"

using namespace clang::ast_matchers;

namespace clang {
namespace {
/// Matches a Stmt whose parent is a CompoundStmt, and which is directly
/// followed by a Stmt matching the inner matcher.
AST_MATCHER_P(Stmt, nextStmt, ast_matchers::internal::Matcher<Stmt>,
              InnerMatcher) {
  DynTypedNodeList Parents = Finder->getASTContext().getParents(Node);
  if (Parents.size() != 1)
    return false;

  auto *C = Parents[0].get<CompoundStmt>();
  if (!C)
    return false;

  const auto *I = llvm::find(C->body(), &Node);
  assert(I != C->body_end() && "C is parent of Node");
  if (++I == C->body_end())
    return false; // Node is last statement.

  return InnerMatcher.matches(**I, Finder, Builder);
}
} // namespace

namespace tidy {
namespace readability {

void UseAnyOfAllOfCheck::registerMatchers(MatchFinder *Finder) {
  auto Returns = [](bool V) {
    return returnStmt(hasReturnValue(cxxBoolLiteral(equals(V))));
  };

  auto ReturnsButNotTrue =
      returnStmt(hasReturnValue(unless(cxxBoolLiteral(equals(true)))));
  auto ReturnsButNotFalse =
      returnStmt(hasReturnValue(unless(cxxBoolLiteral(equals(false)))));

  Finder->addMatcher(
      cxxForRangeStmt(
          nextStmt(Returns(false).bind("final_return")),
          hasBody(allOf(hasDescendant(Returns(true)),
                        unless(anyOf(hasDescendant(breakStmt()),
                                     hasDescendant(gotoStmt()),
                                     hasDescendant(ReturnsButNotTrue))))))
          .bind("any_of_loop"),
      this);

  Finder->addMatcher(
      cxxForRangeStmt(
          nextStmt(Returns(true).bind("final_return")),
          hasBody(allOf(hasDescendant(Returns(false)),
                        unless(anyOf(hasDescendant(breakStmt()),
                                     hasDescendant(gotoStmt()),
                                     hasDescendant(ReturnsButNotFalse))))))
          .bind("all_of_loop"),
      this);
}

static bool isViableLoop(const CXXForRangeStmt &S, ASTContext &Context) {

  ExprMutationAnalyzer Mutations(*S.getBody(), Context);
  if (Mutations.isMutated(S.getLoopVariable()))
    return false;
  const auto Matches =
      match(findAll(declRefExpr().bind("decl_ref")), *S.getBody(), Context);

  return llvm::none_of(Matches, [&Mutations](auto &DeclRef) {
    // TODO: allow modifications of loop-local variables
    return Mutations.isMutated(
        DeclRef.template getNodeAs<DeclRefExpr>("decl_ref")->getDecl());
  });
}

void UseAnyOfAllOfCheck::check(const MatchFinder::MatchResult &Result) {

  if (const auto *S = Result.Nodes.getNodeAs<CXXForRangeStmt>("any_of_loop")) {
    if (!isViableLoop(*S, *Result.Context))
      return;

    diag(S->getForLoc(), "replace loop by 'std%select{|::ranges}0::any_of()'")
        << getLangOpts().CPlusPlus20;
  } else if (const auto *S =
                 Result.Nodes.getNodeAs<CXXForRangeStmt>("all_of_loop")) {
    if (!isViableLoop(*S, *Result.Context))
      return;

    diag(S->getForLoc(), "replace loop by 'std%select{|::ranges}0::all_of()'")
        << getLangOpts().CPlusPlus20;
  }
}

} // namespace readability
} // namespace tidy
} // namespace clang
