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

using namespace clang::ast_matchers;

namespace clang::tidy::readability {

namespace {

const char *const RedundantReturnDiag = "redundant return statement at the end "
                                        "of a function with a void return type";
const char *const RedundantContinueDiag = "redundant continue statement at the "
                                          "end of loop statement";

bool isLocationInMacroExpansion(const SourceManager &SM, SourceLocation Loc) {
  return SM.isMacroBodyExpansion(Loc) || SM.isMacroArgExpansion(Loc);
}

} // namespace

void RedundantControlFlowCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(
      functionDecl(isDefinition(), returns(voidType()),
                   hasBody(compoundStmt(hasAnySubstatement(
                                            returnStmt(unless(has(expr())))))
                               .bind("return"))),
      this);
  Finder->addMatcher(
      mapAnyOf(forStmt, cxxForRangeStmt, whileStmt, doStmt)
          .with(hasBody(compoundStmt(hasAnySubstatement(continueStmt()))
                            .bind("continue"))),
      this);
}

void RedundantControlFlowCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *Return = Result.Nodes.getNodeAs<CompoundStmt>("return"))
    checkRedundantReturn(Result, Return);
  else if (const auto *Continue =
               Result.Nodes.getNodeAs<CompoundStmt>("continue"))
    checkRedundantContinue(Result, Continue);
}

void RedundantControlFlowCheck::checkRedundantReturn(
    const MatchFinder::MatchResult &Result, const CompoundStmt *Block) {
  CompoundStmt::const_reverse_body_iterator Last = Block->body_rbegin();
  if (const auto *Return = dyn_cast<ReturnStmt>(*Last))
    issueDiagnostic(Result, Block, Return->getSourceRange(),
                    RedundantReturnDiag);
}

void RedundantControlFlowCheck::checkRedundantContinue(
    const MatchFinder::MatchResult &Result, const CompoundStmt *Block) {
  CompoundStmt::const_reverse_body_iterator Last = Block->body_rbegin();
  if (const auto *Continue = dyn_cast<ContinueStmt>(*Last))
    issueDiagnostic(Result, Block, Continue->getSourceRange(),
                    RedundantContinueDiag);
}

void RedundantControlFlowCheck::issueDiagnostic(
    const MatchFinder::MatchResult &Result, const CompoundStmt *const Block,
    const SourceRange &StmtRange, const char *const Diag) {
  SourceManager &SM = *Result.SourceManager;
  if (isLocationInMacroExpansion(SM, StmtRange.getBegin()))
    return;

  CompoundStmt::const_reverse_body_iterator Previous = ++Block->body_rbegin();
  SourceLocation Start;
  if (Previous != Block->body_rend())
    Start = Lexer::findLocationAfterToken(
        cast<Stmt>(*Previous)->getEndLoc(), tok::semi, SM, getLangOpts(),
        /*SkipTrailingWhitespaceAndNewLine=*/true);
  if (!Start.isValid())
    Start = StmtRange.getBegin();
  auto RemovedRange = CharSourceRange::getCharRange(
      Start, Lexer::findLocationAfterToken(
                 StmtRange.getEnd(), tok::semi, SM, getLangOpts(),
                 /*SkipTrailingWhitespaceAndNewLine=*/true));

  diag(StmtRange.getBegin(), Diag) << FixItHint::CreateRemoval(RemovedRange);
}

} // namespace clang::tidy::readability
