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

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace abseil {

void UpgradeDurationConversionsCheck::registerMatchers(MatchFinder *Finder) {
  // For the arithmetic calls, we match only the uses of the templated operators
  // where the template parameter is not a built-in type. This means the
  // instantiation makes use of an available user defined conversion to
  // `int64_t`.
  //
  // The implementation of these templates will be updated to fail SFINAE for
  // non-integral types. We match them to suggest an explicit cast.

  // Match expressions like `a *= b` and `a /= b` where `a` has type
  // `absl::Duration` and `b` is not of a built-in type.
  Finder->addMatcher(
      cxxOperatorCallExpr(
          argumentCountIs(2),
          hasArgument(
              0, expr(hasType(cxxRecordDecl(hasName("::absl::Duration"))))),
          hasArgument(1, expr().bind("arg")),
          callee(functionDecl(
              hasParent(functionTemplateDecl()),
              unless(hasTemplateArgument(0, refersToType(builtinType()))),
              hasAnyName("operator*=", "operator/="))))
          .bind("OuterExpr"),
      this);

  // Match expressions like `a.operator*=(b)` and `a.operator/=(b)` where `a`
  // has type `absl::Duration` and `b` is not of a built-in type.
  Finder->addMatcher(
      cxxMemberCallExpr(
          callee(cxxMethodDecl(
              ofClass(cxxRecordDecl(hasName("::absl::Duration"))),
              hasParent(functionTemplateDecl()),
              unless(hasTemplateArgument(0, refersToType(builtinType()))),
              hasAnyName("operator*=", "operator/="))),
          argumentCountIs(1), hasArgument(0, expr().bind("arg")))
          .bind("OuterExpr"),
      this);

  // Match expressions like `a * b`, `a / b`, `operator*(a, b)`, and
  // `operator/(a, b)` where `a` has type `absl::Duration` and `b` is not of a
  // built-in type.
  Finder->addMatcher(
      callExpr(callee(functionDecl(
                   hasParent(functionTemplateDecl()),
                   unless(hasTemplateArgument(0, refersToType(builtinType()))),
                   hasAnyName("::absl::operator*", "::absl::operator/"))),
               argumentCountIs(2),
               hasArgument(0, expr(hasType(
                                  cxxRecordDecl(hasName("::absl::Duration"))))),
               hasArgument(1, expr().bind("arg")))
          .bind("OuterExpr"),
      this);

  // Match expressions like `a * b` and `operator*(a, b)` where `a` is not of a
  // built-in type and `b` has type `absl::Duration`.
  Finder->addMatcher(
      callExpr(callee(functionDecl(
                   hasParent(functionTemplateDecl()),
                   unless(hasTemplateArgument(0, refersToType(builtinType()))),
                   hasName("::absl::operator*"))),
               argumentCountIs(2), hasArgument(0, expr().bind("arg")),
               hasArgument(1, expr(hasType(
                                  cxxRecordDecl(hasName("::absl::Duration"))))))
          .bind("OuterExpr"),
      this);

  // For the factory functions, we match only the non-templated overloads that
  // take an `int64_t` parameter. Within these calls, we care about implicit
  // casts through a user defined conversion to `int64_t`.
  //
  // The factory functions will be updated to be templated and SFINAE on whether
  // the template parameter is an integral type. This complements the already
  // existing templated overloads that only accept floating point types.

  // Match calls like:
  //   `absl::Nanoseconds(x)`
  //   `absl::Microseconds(x)`
  //   `absl::Milliseconds(x)`
  //   `absl::Seconds(x)`
  //   `absl::Minutes(x)`
  //   `absl::Hours(x)`
  // where `x` is not of a built-in type.
  Finder->addMatcher(
      traverse(TK_AsIs, implicitCastExpr(
                            anyOf(hasCastKind(CK_UserDefinedConversion),
                                  has(implicitCastExpr(
                                      hasCastKind(CK_UserDefinedConversion)))),
                            hasParent(callExpr(
                                callee(functionDecl(
                                    DurationFactoryFunction(),
                                    unless(hasParent(functionTemplateDecl())))),
                                hasArgument(0, expr().bind("arg")))))
                            .bind("OuterExpr")),
      this);
}

void UpgradeDurationConversionsCheck::check(
    const MatchFinder::MatchResult &Result) {
  const llvm::StringRef Message =
      "implicit conversion to 'int64_t' is deprecated in this context; use an "
      "explicit cast instead";

  TraversalKindScope RAII(*Result.Context, TK_AsIs);

  const auto *ArgExpr = Result.Nodes.getNodeAs<Expr>("arg");
  SourceLocation Loc = ArgExpr->getBeginLoc();

  const auto *OuterExpr = Result.Nodes.getNodeAs<Expr>("OuterExpr");

  if (!match(isInTemplateInstantiation(), *OuterExpr, *Result.Context)
           .empty()) {
    if (MatchedTemplateLocations.count(Loc) == 0) {
      // For each location matched in a template instantiation, we check if the
      // location can also be found in `MatchedTemplateLocations`. If it is not
      // found, that means the expression did not create a match without the
      // instantiation and depends on template parameters. A manual fix is
      // probably required so we provide only a warning.
      diag(Loc, Message);
    }
    return;
  }

  // We gather source locations from template matches not in template
  // instantiations for future matches.
  internal::Matcher<Stmt> IsInsideTemplate =
      hasAncestor(decl(anyOf(classTemplateDecl(), functionTemplateDecl())));
  if (!match(IsInsideTemplate, *ArgExpr, *Result.Context).empty())
    MatchedTemplateLocations.insert(Loc);

  DiagnosticBuilder Diag = diag(Loc, Message);
  CharSourceRange SourceRange = Lexer::makeFileCharRange(
      CharSourceRange::getTokenRange(ArgExpr->getSourceRange()),
      *Result.SourceManager, Result.Context->getLangOpts());
  if (SourceRange.isInvalid())
    // An invalid source range likely means we are inside a macro body. A manual
    // fix is likely needed so we do not create a fix-it hint.
    return;

  Diag << FixItHint::CreateInsertion(SourceRange.getBegin(),
                                     "static_cast<int64_t>(")
       << FixItHint::CreateInsertion(SourceRange.getEnd(), ")");
}

} // namespace abseil
} // namespace tidy
} // namespace clang
