//===--- QualifiedAutoCheck.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 "QualifiedAutoCheck.h"
#include "../utils/LexerUtils.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace readability {

namespace {

// FIXME move to ASTMatchers
AST_MATCHER_P(QualType, hasUnqualifiedType,
              ast_matchers::internal::Matcher<QualType>, InnerMatcher) {
  return InnerMatcher.matches(Node.getUnqualifiedType(), Finder, Builder);
}

enum class Qualifier { Const, Volatile, Restrict };

llvm::Optional<Token> findQualToken(const VarDecl *Decl, Qualifier Qual,
                                    const MatchFinder::MatchResult &Result) {
  // Since either of the locs can be in a macro, use `makeFileCharRange` to be
  // sure that we have a consistent `CharSourceRange`, located entirely in the
  // source file.

  assert((Qual == Qualifier::Const || Qual == Qualifier::Volatile ||
          Qual == Qualifier::Restrict) &&
         "Invalid Qualifier");

  SourceLocation BeginLoc = Decl->getQualifierLoc().getBeginLoc();
  if (BeginLoc.isInvalid())
    BeginLoc = Decl->getBeginLoc();
  SourceLocation EndLoc = Decl->getLocation();

  CharSourceRange FileRange = Lexer::makeFileCharRange(
      CharSourceRange::getCharRange(BeginLoc, EndLoc), *Result.SourceManager,
      Result.Context->getLangOpts());

  if (FileRange.isInvalid())
    return llvm::None;

  tok::TokenKind Tok =
      Qual == Qualifier::Const
          ? tok::kw_const
          : Qual == Qualifier::Volatile ? tok::kw_volatile : tok::kw_restrict;

  return utils::lexer::getQualifyingToken(Tok, FileRange, *Result.Context,
                                          *Result.SourceManager);
}

llvm::Optional<SourceRange>
getTypeSpecifierLocation(const VarDecl *Var,
                         const MatchFinder::MatchResult &Result) {
  SourceRange TypeSpecifier(
      Var->getTypeSpecStartLoc(),
      Var->getTypeSpecEndLoc().getLocWithOffset(Lexer::MeasureTokenLength(
          Var->getTypeSpecEndLoc(), *Result.SourceManager,
          Result.Context->getLangOpts())));

  if (TypeSpecifier.getBegin().isMacroID() ||
      TypeSpecifier.getEnd().isMacroID())
    return llvm::None;
  return TypeSpecifier;
}

llvm::Optional<SourceRange> mergeReplacementRange(SourceRange &TypeSpecifier,
                                                  const Token &ConstToken) {
  if (TypeSpecifier.getBegin().getLocWithOffset(-1) == ConstToken.getEndLoc()) {
    TypeSpecifier.setBegin(ConstToken.getLocation());
    return llvm::None;
  }
  if (TypeSpecifier.getEnd().getLocWithOffset(1) == ConstToken.getLocation()) {
    TypeSpecifier.setEnd(ConstToken.getEndLoc());
    return llvm::None;
  }
  return SourceRange(ConstToken.getLocation(), ConstToken.getEndLoc());
}

bool isPointerConst(QualType QType) {
  QualType Pointee = QType->getPointeeType();
  assert(!Pointee.isNull() && "can't have a null Pointee");
  return Pointee.isConstQualified();
}

bool isAutoPointerConst(QualType QType) {
  QualType Pointee =
      cast<AutoType>(QType->getPointeeType().getTypePtr())->desugar();
  assert(!Pointee.isNull() && "can't have a null Pointee");
  return Pointee.isConstQualified();
}

} // namespace

void QualifiedAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "AddConstToQualified", AddConstToQualified);
}

void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) {
  auto ExplicitSingleVarDecl =
      [](const ast_matchers::internal::Matcher<VarDecl> &InnerMatcher,
         llvm::StringRef ID) {
        return declStmt(
            unless(isInTemplateInstantiation()),
            hasSingleDecl(
                varDecl(unless(isImplicit()), InnerMatcher).bind(ID)));
      };
  auto ExplicitSingleVarDeclInTemplate =
      [](const ast_matchers::internal::Matcher<VarDecl> &InnerMatcher,
         llvm::StringRef ID) {
        return declStmt(
            isInTemplateInstantiation(),
            hasSingleDecl(
                varDecl(unless(isImplicit()), InnerMatcher).bind(ID)));
      };

  auto IsBoundToType = refersToType(equalsBoundNode("type"));
  auto UnlessFunctionType = unless(hasUnqualifiedDesugaredType(functionType()));
  auto IsAutoDeducedToPointer = [](const auto &...InnerMatchers) {
    return autoType(hasDeducedType(
        hasUnqualifiedDesugaredType(pointerType(pointee(InnerMatchers...)))));
  };

  Finder->addMatcher(
      ExplicitSingleVarDecl(hasType(IsAutoDeducedToPointer(UnlessFunctionType)),
                            "auto"),
      this);

  Finder->addMatcher(
      ExplicitSingleVarDeclInTemplate(
          allOf(hasType(IsAutoDeducedToPointer(
                    hasUnqualifiedType(qualType().bind("type")),
                    UnlessFunctionType)),
                anyOf(hasAncestor(
                          functionDecl(hasAnyTemplateArgument(IsBoundToType))),
                      hasAncestor(classTemplateSpecializationDecl(
                          hasAnyTemplateArgument(IsBoundToType))))),
          "auto"),
      this);
  if (!AddConstToQualified)
    return;
  Finder->addMatcher(ExplicitSingleVarDecl(
                         hasType(pointerType(pointee(autoType()))), "auto_ptr"),
                     this);
  Finder->addMatcher(
      ExplicitSingleVarDecl(hasType(lValueReferenceType(pointee(autoType()))),
                            "auto_ref"),
      this);
}

void QualifiedAutoCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto")) {
    SourceRange TypeSpecifier;
    if (llvm::Optional<SourceRange> TypeSpec =
            getTypeSpecifierLocation(Var, Result)) {
      TypeSpecifier = *TypeSpec;
    } else
      return;

    llvm::SmallVector<SourceRange, 4> RemoveQualifiersRange;
    auto CheckQualifier = [&](bool IsPresent, Qualifier Qual) {
      if (IsPresent) {
        llvm::Optional<Token> Token = findQualToken(Var, Qual, Result);
        if (!Token || Token->getLocation().isMacroID())
          return true; // Disregard this VarDecl.
        if (llvm::Optional<SourceRange> Result =
                mergeReplacementRange(TypeSpecifier, *Token))
          RemoveQualifiersRange.push_back(*Result);
      }
      return false;
    };

    bool IsLocalConst = Var->getType().isLocalConstQualified();
    bool IsLocalVolatile = Var->getType().isLocalVolatileQualified();
    bool IsLocalRestrict = Var->getType().isLocalRestrictQualified();

    if (CheckQualifier(IsLocalConst, Qualifier::Const) ||
        CheckQualifier(IsLocalVolatile, Qualifier::Volatile) ||
        CheckQualifier(IsLocalRestrict, Qualifier::Restrict))
      return;

    // Check for bridging the gap between the asterisk and name.
    if (Var->getLocation() == TypeSpecifier.getEnd().getLocWithOffset(1))
      TypeSpecifier.setEnd(TypeSpecifier.getEnd().getLocWithOffset(1));

    CharSourceRange FixItRange = CharSourceRange::getCharRange(TypeSpecifier);
    if (FixItRange.isInvalid())
      return;

    SourceLocation FixitLoc = FixItRange.getBegin();
    for (SourceRange &Range : RemoveQualifiersRange) {
      if (Range.getBegin() < FixitLoc)
        FixitLoc = Range.getBegin();
    }

    std::string ReplStr = [&] {
      llvm::StringRef PtrConst = isPointerConst(Var->getType()) ? "const " : "";
      llvm::StringRef LocalConst = IsLocalConst ? "const " : "";
      llvm::StringRef LocalVol = IsLocalVolatile ? "volatile " : "";
      llvm::StringRef LocalRestrict = IsLocalRestrict ? "__restrict " : "";
      return (PtrConst + "auto *" + LocalConst + LocalVol + LocalRestrict)
          .str();
    }();

    DiagnosticBuilder Diag =
        diag(FixitLoc,
             "'%select{|const }0%select{|volatile }1%select{|__restrict }2auto "
             "%3' can be declared as '%4%3'")
        << IsLocalConst << IsLocalVolatile << IsLocalRestrict << Var->getName()
        << ReplStr;

    for (SourceRange &Range : RemoveQualifiersRange) {
      Diag << FixItHint::CreateRemoval(CharSourceRange::getCharRange(Range));
    }

    Diag << FixItHint::CreateReplacement(FixItRange, ReplStr);
    return;
  }
  if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto_ptr")) {
    if (!isPointerConst(Var->getType()))
      return; // Pointer isn't const, no need to add const qualifier.
    if (!isAutoPointerConst(Var->getType()))
      return; // Const isn't wrapped in the auto type, so must be declared
              // explicitly.

    if (Var->getType().isLocalConstQualified()) {
      llvm::Optional<Token> Token =
          findQualToken(Var, Qualifier::Const, Result);
      if (!Token || Token->getLocation().isMacroID())
        return;
    }
    if (Var->getType().isLocalVolatileQualified()) {
      llvm::Optional<Token> Token =
          findQualToken(Var, Qualifier::Volatile, Result);
      if (!Token || Token->getLocation().isMacroID())
        return;
    }
    if (Var->getType().isLocalRestrictQualified()) {
      llvm::Optional<Token> Token =
          findQualToken(Var, Qualifier::Restrict, Result);
      if (!Token || Token->getLocation().isMacroID())
        return;
    }

    if (llvm::Optional<SourceRange> TypeSpec =
            getTypeSpecifierLocation(Var, Result)) {
      if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() ||
          TypeSpec->getEnd().isMacroID())
        return;
      SourceLocation InsertPos = TypeSpec->getBegin();
      diag(InsertPos,
           "'auto *%select{|const }0%select{|volatile }1%2' can be declared as "
           "'const auto *%select{|const }0%select{|volatile }1%2'")
          << Var->getType().isLocalConstQualified()
          << Var->getType().isLocalVolatileQualified() << Var->getName()
          << FixItHint::CreateInsertion(InsertPos, "const ");
    }
    return;
  }
  if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto_ref")) {
    if (!isPointerConst(Var->getType()))
      return; // Pointer isn't const, no need to add const qualifier.
    if (!isAutoPointerConst(Var->getType()))
      // Const isn't wrapped in the auto type, so must be declared explicitly.
      return;

    if (llvm::Optional<SourceRange> TypeSpec =
            getTypeSpecifierLocation(Var, Result)) {
      if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() ||
          TypeSpec->getEnd().isMacroID())
        return;
      SourceLocation InsertPos = TypeSpec->getBegin();
      diag(InsertPos, "'auto &%0' can be declared as 'const auto &%0'")
          << Var->getName() << FixItHint::CreateInsertion(InsertPos, "const ");
    }
    return;
  }
}

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