//===--- MagicNumbersCheck.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
//
//===----------------------------------------------------------------------===//
//
// A checker for magic numbers: integer or floating point literals embedded
// in the code, outside the definition of a constant or an enumeration.
//
//===----------------------------------------------------------------------===//

#include "MagicNumbersCheck.h"
#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Type.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>

using namespace clang::ast_matchers;

namespace clang {

static bool isUsedToInitializeAConstant(const MatchFinder::MatchResult &Result,
                                        const DynTypedNode &Node) {

  const auto *AsDecl = Node.get<DeclaratorDecl>();
  if (AsDecl) {
    if (AsDecl->getType().isConstQualified())
      return true;

    return AsDecl->isImplicit();
  }

  if (Node.get<EnumConstantDecl>())
    return true;

  return llvm::any_of(Result.Context->getParents(Node),
                      [&Result](const DynTypedNode &Parent) {
                        return isUsedToInitializeAConstant(Result, Parent);
                      });
}

static bool isUsedToDefineATypeAlias(const MatchFinder::MatchResult &Result,
                                     const DynTypedNode &Node) {

  if (Node.get<TypeAliasDecl>() || Node.get<TypedefNameDecl>())
    return true;

  return llvm::any_of(Result.Context->getParents(Node),
                      [&Result](const DynTypedNode &Parent) {
                        return isUsedToDefineATypeAlias(Result, Parent);
                      });
}

static bool isUsedToDefineABitField(const MatchFinder::MatchResult &Result,
                                    const DynTypedNode &Node) {
  const auto *AsFieldDecl = Node.get<FieldDecl>();
  if (AsFieldDecl && AsFieldDecl->isBitField())
    return true;

  return llvm::any_of(Result.Context->getParents(Node),
                      [&Result](const DynTypedNode &Parent) {
                        return isUsedToDefineABitField(Result, Parent);
                      });
}

namespace tidy::readability {

const char DefaultIgnoredIntegerValues[] = "1;2;3;4;";
const char DefaultIgnoredFloatingPointValues[] = "1.0;100.0;";

MagicNumbersCheck::MagicNumbersCheck(StringRef Name, ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      IgnoreAllFloatingPointValues(
          Options.get("IgnoreAllFloatingPointValues", false)),
      IgnoreBitFieldsWidths(Options.get("IgnoreBitFieldsWidths", true)),
      IgnorePowersOf2IntegerValues(
          Options.get("IgnorePowersOf2IntegerValues", false)),
      IgnoreTypeAliases(Options.get("IgnoreTypeAliases", false)),
      IgnoreUserDefinedLiterals(
          Options.get("IgnoreUserDefinedLiterals", false)),
      RawIgnoredIntegerValues(
          Options.get("IgnoredIntegerValues", DefaultIgnoredIntegerValues)),
      RawIgnoredFloatingPointValues(Options.get(
          "IgnoredFloatingPointValues", DefaultIgnoredFloatingPointValues)) {
  // Process the set of ignored integer values.
  const std::vector<StringRef> IgnoredIntegerValuesInput =
      utils::options::parseStringList(RawIgnoredIntegerValues);
  IgnoredIntegerValues.resize(IgnoredIntegerValuesInput.size());
  llvm::transform(IgnoredIntegerValuesInput, IgnoredIntegerValues.begin(),
                  [](StringRef Value) {
                    int64_t Res = 0;
                    Value.getAsInteger(10, Res);
                    return Res;
                  });
  llvm::sort(IgnoredIntegerValues);

  if (!IgnoreAllFloatingPointValues) {
    // Process the set of ignored floating point values.
    const std::vector<StringRef> IgnoredFloatingPointValuesInput =
        utils::options::parseStringList(RawIgnoredFloatingPointValues);
    IgnoredFloatingPointValues.reserve(IgnoredFloatingPointValuesInput.size());
    IgnoredDoublePointValues.reserve(IgnoredFloatingPointValuesInput.size());
    for (const auto &InputValue : IgnoredFloatingPointValuesInput) {
      llvm::APFloat FloatValue(llvm::APFloat::IEEEsingle());
      auto StatusOrErr =
          FloatValue.convertFromString(InputValue, DefaultRoundingMode);
      assert(StatusOrErr && "Invalid floating point representation");
      consumeError(StatusOrErr.takeError());
      IgnoredFloatingPointValues.push_back(FloatValue.convertToFloat());

      llvm::APFloat DoubleValue(llvm::APFloat::IEEEdouble());
      StatusOrErr =
          DoubleValue.convertFromString(InputValue, DefaultRoundingMode);
      assert(StatusOrErr && "Invalid floating point representation");
      consumeError(StatusOrErr.takeError());
      IgnoredDoublePointValues.push_back(DoubleValue.convertToDouble());
    }
    llvm::sort(IgnoredFloatingPointValues);
    llvm::sort(IgnoredDoublePointValues);
  }
}

void MagicNumbersCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "IgnoreAllFloatingPointValues",
                IgnoreAllFloatingPointValues);
  Options.store(Opts, "IgnoreBitFieldsWidths", IgnoreBitFieldsWidths);
  Options.store(Opts, "IgnorePowersOf2IntegerValues",
                IgnorePowersOf2IntegerValues);
  Options.store(Opts, "IgnoreTypeAliases", IgnoreTypeAliases);
  Options.store(Opts, "IgnoreUserDefinedLiterals", IgnoreUserDefinedLiterals);
  Options.store(Opts, "IgnoredIntegerValues", RawIgnoredIntegerValues);
  Options.store(Opts, "IgnoredFloatingPointValues",
                RawIgnoredFloatingPointValues);
}

void MagicNumbersCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(integerLiteral().bind("integer"), this);
  if (!IgnoreAllFloatingPointValues)
    Finder->addMatcher(floatLiteral().bind("float"), this);
}

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

  TraversalKindScope RAII(*Result.Context, TK_AsIs);

  checkBoundMatch<IntegerLiteral>(Result, "integer");
  checkBoundMatch<FloatingLiteral>(Result, "float");
}

bool MagicNumbersCheck::isConstant(const MatchFinder::MatchResult &Result,
                                   const Expr &ExprResult) const {
  return llvm::any_of(
      Result.Context->getParents(ExprResult),
      [this, &Result](const DynTypedNode &Parent) {
        if (isUsedToInitializeAConstant(Result, Parent))
          return true;

        if (IgnoreTypeAliases && isUsedToDefineATypeAlias(Result, Parent))
          return true;

        // Ignore this instance, because this matches an
        // expanded class enumeration value.
        if (Parent.get<CStyleCastExpr>() &&
            llvm::any_of(
                Result.Context->getParents(Parent),
                [](const DynTypedNode &GrandParent) {
                  return GrandParent.get<SubstNonTypeTemplateParmExpr>() !=
                         nullptr;
                }))
          return true;

        // Ignore this instance, because this match reports the
        // location where the template is defined, not where it
        // is instantiated.
        if (Parent.get<SubstNonTypeTemplateParmExpr>())
          return true;

        // Don't warn on string user defined literals:
        // std::string s = "Hello World"s;
        if (const auto *UDL = Parent.get<UserDefinedLiteral>())
          if (UDL->getLiteralOperatorKind() == UserDefinedLiteral::LOK_String)
            return true;

        return false;
      });
}

bool MagicNumbersCheck::isIgnoredValue(const IntegerLiteral *Literal) const {
  if (Literal->getType()->isBitIntType()) {
    return true;
  }
  const llvm::APInt IntValue = Literal->getValue();
  const int64_t Value = IntValue.getZExtValue();
  if (Value == 0)
    return true;

  if (IgnorePowersOf2IntegerValues && IntValue.isPowerOf2())
    return true;

  return std::binary_search(IgnoredIntegerValues.begin(),
                            IgnoredIntegerValues.end(), Value);
}

bool MagicNumbersCheck::isIgnoredValue(const FloatingLiteral *Literal) const {
  const llvm::APFloat FloatValue = Literal->getValue();
  if (FloatValue.isZero())
    return true;

  if (&FloatValue.getSemantics() == &llvm::APFloat::IEEEsingle()) {
    const float Value = FloatValue.convertToFloat();
    return std::binary_search(IgnoredFloatingPointValues.begin(),
                              IgnoredFloatingPointValues.end(), Value);
  }

  if (&FloatValue.getSemantics() == &llvm::APFloat::IEEEdouble()) {
    const double Value = FloatValue.convertToDouble();
    return std::binary_search(IgnoredDoublePointValues.begin(),
                              IgnoredDoublePointValues.end(), Value);
  }

  return false;
}

bool MagicNumbersCheck::isSyntheticValue(const SourceManager *SourceManager,
                                         const IntegerLiteral *Literal) const {
  const std::pair<FileID, unsigned> FileOffset =
      SourceManager->getDecomposedLoc(Literal->getLocation());
  if (FileOffset.first.isInvalid())
    return false;

  const StringRef BufferIdentifier =
      SourceManager->getBufferOrFake(FileOffset.first).getBufferIdentifier();

  return BufferIdentifier.empty();
}

bool MagicNumbersCheck::isBitFieldWidth(
    const clang::ast_matchers::MatchFinder::MatchResult &Result,
    const IntegerLiteral &Literal) const {
  return IgnoreBitFieldsWidths &&
         llvm::any_of(Result.Context->getParents(Literal),
                      [&Result](const DynTypedNode &Parent) {
                        return isUsedToDefineABitField(Result, Parent);
                      });
}

bool MagicNumbersCheck::isUserDefinedLiteral(
    const clang::ast_matchers::MatchFinder::MatchResult &Result,
    const clang::Expr &Literal) const {
  DynTypedNodeList Parents = Result.Context->getParents(Literal);
  if (Parents.empty())
    return false;
  return Parents[0].get<UserDefinedLiteral>() != nullptr;
}

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