//===- RedundantVoidArgCheck.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 "RedundantVoidArgCheck.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Lexer.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace modernize {

namespace {

// Determine if the given QualType is a nullary function or pointer to same.
bool protoTypeHasNoParms(QualType QT) {
  if (const auto *PT = QT->getAs<PointerType>())
    QT = PT->getPointeeType();
  if (auto *MPT = QT->getAs<MemberPointerType>())
    QT = MPT->getPointeeType();
  if (const auto *FP = QT->getAs<FunctionProtoType>())
    return FP->getNumParams() == 0;
  return false;
}

const char FunctionId[] = "function";
const char TypedefId[] = "typedef";
const char FieldId[] = "field";
const char VarId[] = "var";
const char NamedCastId[] = "named-cast";
const char CStyleCastId[] = "c-style-cast";
const char ExplicitCastId[] = "explicit-cast";
const char LambdaId[] = "lambda";

} // namespace

void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(functionDecl(parameterCountIs(0), unless(isImplicit()),
                                  unless(isInstantiated()), unless(isExternC()))
                         .bind(FunctionId),
                     this);
  Finder->addMatcher(typedefNameDecl(unless(isImplicit())).bind(TypedefId),
                     this);
  auto ParenFunctionType = parenType(innerType(functionType()));
  auto PointerToFunctionType = pointee(ParenFunctionType);
  auto FunctionOrMemberPointer =
      anyOf(hasType(pointerType(PointerToFunctionType)),
            hasType(memberPointerType(PointerToFunctionType)));
  Finder->addMatcher(fieldDecl(FunctionOrMemberPointer).bind(FieldId), this);
  Finder->addMatcher(varDecl(FunctionOrMemberPointer).bind(VarId), this);
  auto CastDestinationIsFunction =
      hasDestinationType(pointsTo(ParenFunctionType));
  Finder->addMatcher(
      cStyleCastExpr(CastDestinationIsFunction).bind(CStyleCastId), this);
  Finder->addMatcher(
      cxxStaticCastExpr(CastDestinationIsFunction).bind(NamedCastId), this);
  Finder->addMatcher(
      cxxReinterpretCastExpr(CastDestinationIsFunction).bind(NamedCastId),
      this);
  Finder->addMatcher(
      cxxConstCastExpr(CastDestinationIsFunction).bind(NamedCastId), this);
  Finder->addMatcher(lambdaExpr().bind(LambdaId), this);
}

void RedundantVoidArgCheck::check(const MatchFinder::MatchResult &Result) {
  const BoundNodes &Nodes = Result.Nodes;
  if (const auto *Function = Nodes.getNodeAs<FunctionDecl>(FunctionId))
    processFunctionDecl(Result, Function);
  else if (const auto *TypedefName =
               Nodes.getNodeAs<TypedefNameDecl>(TypedefId))
    processTypedefNameDecl(Result, TypedefName);
  else if (const auto *Member = Nodes.getNodeAs<FieldDecl>(FieldId))
    processFieldDecl(Result, Member);
  else if (const auto *Var = Nodes.getNodeAs<VarDecl>(VarId))
    processVarDecl(Result, Var);
  else if (const auto *NamedCast =
               Nodes.getNodeAs<CXXNamedCastExpr>(NamedCastId))
    processNamedCastExpr(Result, NamedCast);
  else if (const auto *CStyleCast =
               Nodes.getNodeAs<CStyleCastExpr>(CStyleCastId))
    processExplicitCastExpr(Result, CStyleCast);
  else if (const auto *ExplicitCast =
               Nodes.getNodeAs<ExplicitCastExpr>(ExplicitCastId))
    processExplicitCastExpr(Result, ExplicitCast);
  else if (const auto *Lambda = Nodes.getNodeAs<LambdaExpr>(LambdaId))
    processLambdaExpr(Result, Lambda);
}

void RedundantVoidArgCheck::processFunctionDecl(
    const MatchFinder::MatchResult &Result, const FunctionDecl *Function) {
  const auto *Method = dyn_cast<CXXMethodDecl>(Function);
  SourceLocation Start = Method && Method->getParent()->isLambda()
                             ? Method->getBeginLoc()
                             : Function->getLocation();
  SourceLocation End = Function->getEndLoc();
  if (Function->isThisDeclarationADefinition()) {
    if (const Stmt *Body = Function->getBody()) {
      End = Body->getBeginLoc();
      if (End.isMacroID() &&
          Result.SourceManager->isAtStartOfImmediateMacroExpansion(End))
        End = Result.SourceManager->getExpansionLoc(End);
      End = End.getLocWithOffset(-1);
    }
    removeVoidArgumentTokens(Result, SourceRange(Start, End),
                             "function definition");
  } else
    removeVoidArgumentTokens(Result, SourceRange(Start, End),
                             "function declaration");
}

bool isMacroIdentifier(const IdentifierTable &Idents, const Token &ProtoToken) {
  if (!ProtoToken.is(tok::TokenKind::raw_identifier))
    return false;

  IdentifierTable::iterator It = Idents.find(ProtoToken.getRawIdentifier());
  if (It == Idents.end())
    return false;

  return It->second->hadMacroDefinition();
}

void RedundantVoidArgCheck::removeVoidArgumentTokens(
    const ast_matchers::MatchFinder::MatchResult &Result, SourceRange Range,
    StringRef GrammarLocation) {
  CharSourceRange CharRange =
      Lexer::makeFileCharRange(CharSourceRange::getTokenRange(Range),
                               *Result.SourceManager, getLangOpts());

  std::string DeclText =
      Lexer::getSourceText(CharRange, *Result.SourceManager, getLangOpts())
          .str();
  Lexer PrototypeLexer(CharRange.getBegin(), getLangOpts(), DeclText.data(),
                       DeclText.data(), DeclText.data() + DeclText.size());
  enum class TokenState {
    Start,
    MacroId,
    MacroLeftParen,
    MacroArguments,
    LeftParen,
    Void,
  };
  TokenState State = TokenState::Start;
  Token VoidToken;
  Token ProtoToken;
  const IdentifierTable &Idents = Result.Context->Idents;
  int MacroLevel = 0;
  std::string Diagnostic =
      ("redundant void argument list in " + GrammarLocation).str();

  while (!PrototypeLexer.LexFromRawLexer(ProtoToken)) {
    switch (State) {
    case TokenState::Start:
      if (ProtoToken.is(tok::TokenKind::l_paren))
        State = TokenState::LeftParen;
      else if (isMacroIdentifier(Idents, ProtoToken))
        State = TokenState::MacroId;
      break;
    case TokenState::MacroId:
      if (ProtoToken.is(tok::TokenKind::l_paren))
        State = TokenState::MacroLeftParen;
      else
        State = TokenState::Start;
      break;
    case TokenState::MacroLeftParen:
      ++MacroLevel;
      if (ProtoToken.is(tok::TokenKind::raw_identifier)) {
        if (isMacroIdentifier(Idents, ProtoToken))
          State = TokenState::MacroId;
        else
          State = TokenState::MacroArguments;
      } else if (ProtoToken.is(tok::TokenKind::r_paren)) {
        --MacroLevel;
        if (MacroLevel == 0)
          State = TokenState::Start;
        else
          State = TokenState::MacroId;
      } else
        State = TokenState::MacroArguments;
      break;
    case TokenState::MacroArguments:
      if (isMacroIdentifier(Idents, ProtoToken))
        State = TokenState::MacroLeftParen;
      else if (ProtoToken.is(tok::TokenKind::r_paren)) {
        --MacroLevel;
        if (MacroLevel == 0)
          State = TokenState::Start;
      }
      break;
    case TokenState::LeftParen:
      if (ProtoToken.is(tok::TokenKind::raw_identifier)) {
        if (isMacroIdentifier(Idents, ProtoToken))
          State = TokenState::MacroId;
        else if (ProtoToken.getRawIdentifier() == "void") {
          State = TokenState::Void;
          VoidToken = ProtoToken;
        }
      } else if (ProtoToken.is(tok::TokenKind::l_paren))
        State = TokenState::LeftParen;
      else
        State = TokenState::Start;
      break;
    case TokenState::Void:
      State = TokenState::Start;
      if (ProtoToken.is(tok::TokenKind::r_paren))
        removeVoidToken(VoidToken, Diagnostic);
      else if (ProtoToken.is(tok::TokenKind::l_paren))
        State = TokenState::LeftParen;
      break;
    }
  }

  if (State == TokenState::Void && ProtoToken.is(tok::TokenKind::r_paren))
    removeVoidToken(VoidToken, Diagnostic);
}

void RedundantVoidArgCheck::removeVoidToken(Token VoidToken,
                                            StringRef Diagnostic) {
  SourceLocation VoidLoc = VoidToken.getLocation();
  diag(VoidLoc, Diagnostic) << FixItHint::CreateRemoval(VoidLoc);
}

void RedundantVoidArgCheck::processTypedefNameDecl(
    const MatchFinder::MatchResult &Result,
    const TypedefNameDecl *TypedefName) {
  if (protoTypeHasNoParms(TypedefName->getUnderlyingType()))
    removeVoidArgumentTokens(Result, TypedefName->getSourceRange(),
                             isa<TypedefDecl>(TypedefName) ? "typedef"
                                                           : "type alias");
}

void RedundantVoidArgCheck::processFieldDecl(
    const MatchFinder::MatchResult &Result, const FieldDecl *Member) {
  if (protoTypeHasNoParms(Member->getType()))
    removeVoidArgumentTokens(Result, Member->getSourceRange(),
                             "field declaration");
}

void RedundantVoidArgCheck::processVarDecl(
    const MatchFinder::MatchResult &Result, const VarDecl *Var) {
  if (protoTypeHasNoParms(Var->getType())) {
    SourceLocation Begin = Var->getBeginLoc();
    if (Var->hasInit()) {
      SourceLocation InitStart =
          Result.SourceManager->getExpansionLoc(Var->getInit()->getBeginLoc())
              .getLocWithOffset(-1);
      removeVoidArgumentTokens(Result, SourceRange(Begin, InitStart),
                               "variable declaration with initializer");
    } else
      removeVoidArgumentTokens(Result, Var->getSourceRange(),
                               "variable declaration");
  }
}

void RedundantVoidArgCheck::processNamedCastExpr(
    const MatchFinder::MatchResult &Result, const CXXNamedCastExpr *NamedCast) {
  if (protoTypeHasNoParms(NamedCast->getTypeAsWritten()))
    removeVoidArgumentTokens(
        Result,
        NamedCast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange(),
        "named cast");
}

void RedundantVoidArgCheck::processExplicitCastExpr(
    const MatchFinder::MatchResult &Result,
    const ExplicitCastExpr *ExplicitCast) {
  if (protoTypeHasNoParms(ExplicitCast->getTypeAsWritten()))
    removeVoidArgumentTokens(Result, ExplicitCast->getSourceRange(),
                             "cast expression");
}

void RedundantVoidArgCheck::processLambdaExpr(
    const MatchFinder::MatchResult &Result, const LambdaExpr *Lambda) {
  if (Lambda->getLambdaClass()->getLambdaCallOperator()->getNumParams() == 0 &&
      Lambda->hasExplicitParameters()) {
    SourceManager *SM = Result.SourceManager;
    TypeLoc TL = Lambda->getLambdaClass()->getLambdaTypeInfo()->getTypeLoc();
    removeVoidArgumentTokens(Result,
                             {SM->getSpellingLoc(TL.getBeginLoc()),
                              SM->getSpellingLoc(TL.getEndLoc())},
                             "lambda expression");
  }
}

} // namespace modernize
} // namespace tidy
} // namespace clang
