//===--- RewriteRule.h - RewriteRule class ----------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
///  \file
///  Defines the RewriteRule class and related functions for creating,
///  modifying and interpreting RewriteRules.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_REWRITE_RULE_H_
#define LLVM_CLANG_TOOLING_TRANSFORMER_REWRITE_RULE_H_

#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/Tooling/Refactoring/AtomicChange.h"
#include "clang/Tooling/Transformer/MatchConsumer.h"
#include "clang/Tooling/Transformer/RangeSelector.h"
#include "llvm/ADT/Any.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Error.h"
#include <functional>
#include <string>
#include <utility>

namespace clang {
namespace transformer {
// Specifies how to interpret an edit.
enum class EditKind {
  // Edits a source range in the file.
  Range,
  // Inserts an include in the file. The `Replacement` field is the name of the
  // newly included file.
  AddInclude,
};

/// A concrete description of a source edit, represented by a character range in
/// the source to be replaced and a corresponding replacement string.
struct Edit {
  EditKind Kind = EditKind::Range;
  CharSourceRange Range;
  std::string Replacement;
  llvm::Any Metadata;
};

/// Format of the path in an include directive -- angle brackets or quotes.
enum class IncludeFormat {
  Quoted,
  Angled,
};

/// Maps a match result to a list of concrete edits (with possible
/// failure). This type is a building block of rewrite rules, but users will
/// generally work in terms of `ASTEdit`s (below) rather than directly in terms
/// of `EditGenerator`.
using EditGenerator = MatchConsumer<llvm::SmallVector<Edit, 1>>;

using TextGenerator = std::shared_ptr<MatchComputation<std::string>>;

using AnyGenerator = MatchConsumer<llvm::Any>;

// Description of a source-code edit, expressed in terms of an AST node.
// Includes: an ID for the (bound) node, a selector for source related to the
// node, a replacement and, optionally, an explanation for the edit.
//
// * Target: the source code impacted by the rule. This identifies an AST node,
//   or part thereof (\c Part), whose source range indicates the extent of the
//   replacement applied by the replacement term.  By default, the extent is the
//   node matched by the pattern term (\c NodePart::Node). Target's are typed
//   (\c Kind), which guides the determination of the node extent.
//
// * Replacement: a function that produces a replacement string for the target,
//   based on the match result.
//
// * Note: (optional) a note specifically for this edit, potentially referencing
//   elements of the match.  This will be displayed to the user, where possible;
//   for example, in clang-tidy diagnostics.  Use of notes should be rare --
//   explanations of the entire rewrite should be set in the rule
//   (`RewriteRule::Explanation`) instead.  Notes serve the rare cases wherein
//   edit-specific diagnostics are required.
//
// `ASTEdit` should be built using the `change` convenience functions. For
// example,
// \code
//   changeTo(name(fun), cat("Frodo"))
// \endcode
// Or, if we use Stencil for the TextGenerator:
// \code
//   using stencil::cat;
//   changeTo(statement(thenNode), cat("{", thenNode, "}"))
//   changeTo(callArgs(call), cat(x, ",", y))
// \endcode
// Or, if you are changing the node corresponding to the rule's matcher, you can
// use the single-argument override of \c change:
// \code
//   changeTo(cat("different_expr"))
// \endcode
struct ASTEdit {
  EditKind Kind = EditKind::Range;
  RangeSelector TargetRange;
  TextGenerator Replacement;
  TextGenerator Note;
  // Not all transformations will want or need to attach metadata and therefore
  // should not be required to do so.
  AnyGenerator Metadata = [](const ast_matchers::MatchFinder::MatchResult &)
      -> llvm::Expected<llvm::Any> {
    return llvm::Expected<llvm::Any>(llvm::Any());
  };
};

/// Generates a single (specified) edit.
EditGenerator edit(ASTEdit E);

/// Lifts a list of `ASTEdit`s into an `EditGenerator`.
///
/// The `EditGenerator` will return an empty vector if any of the edits apply to
/// portions of the source that are ineligible for rewriting (certain
/// interactions with macros, for example) and it will fail if any invariants
/// are violated relating to bound nodes in the match.  However, it does not
/// fail in the case of conflicting edits -- conflict handling is left to
/// clients.  We recommend use of the \c AtomicChange or \c Replacements classes
/// for assistance in detecting such conflicts.
EditGenerator editList(llvm::SmallVector<ASTEdit, 1> Edits);

/// Generates no edits.
inline EditGenerator noEdits() { return editList({}); }

/// Generates a single, no-op edit anchored at the start location of the
/// specified range. A `noopEdit` may be preferred over `noEdits` to associate a
/// diagnostic `Explanation` with the rule.
EditGenerator noopEdit(RangeSelector Anchor);

/// Version of `ifBound` specialized to `ASTEdit`.
inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit,
                             ASTEdit FalseEdit) {
  return ifBound(std::move(ID), edit(std::move(TrueEdit)),
                 edit(std::move(FalseEdit)));
}

/// Version of `ifBound` that has no "False" branch. If the node is not bound,
/// then no edits are produced.
inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit) {
  return ifBound(std::move(ID), edit(std::move(TrueEdit)), noEdits());
}

/// Flattens a list of generators into a single generator whose elements are the
/// concatenation of the results of the argument generators.
EditGenerator flattenVector(SmallVector<EditGenerator, 2> Generators);

namespace detail {
/// Helper function to construct an \c EditGenerator. Overloaded for common
/// cases so that user doesn't need to specify which factory function to
/// use. This pattern gives benefits similar to implicit constructors, while
/// maintaing a higher degree of explicitness.
inline EditGenerator injectEdits(ASTEdit E) { return edit(std::move(E)); }
inline EditGenerator injectEdits(EditGenerator G) { return G; }
} // namespace detail

template <typename... Ts> EditGenerator flatten(Ts &&...Edits) {
  return flattenVector({detail::injectEdits(std::forward<Ts>(Edits))...});
}

// Every rewrite rule is triggered by a match against some AST node.
// Transformer guarantees that this ID is bound to the triggering node whenever
// a rewrite rule is applied.
extern const char RootID[];

/// Replaces a portion of the source text with \p Replacement.
ASTEdit changeTo(RangeSelector Target, TextGenerator Replacement);
/// DEPRECATED: use \c changeTo.
inline ASTEdit change(RangeSelector Target, TextGenerator Replacement) {
  return changeTo(std::move(Target), std::move(Replacement));
}

/// Replaces the entirety of a RewriteRule's match with \p Replacement.  For
/// example, to replace a function call, one could write:
/// \code
///   makeRule(callExpr(callee(functionDecl(hasName("foo")))),
///            changeTo(cat("bar()")))
/// \endcode
inline ASTEdit changeTo(TextGenerator Replacement) {
  return changeTo(node(RootID), std::move(Replacement));
}
/// DEPRECATED: use \c changeTo.
inline ASTEdit change(TextGenerator Replacement) {
  return changeTo(std::move(Replacement));
}

/// Inserts \p Replacement before \p S, leaving the source selected by \S
/// unchanged.
inline ASTEdit insertBefore(RangeSelector S, TextGenerator Replacement) {
  return changeTo(before(std::move(S)), std::move(Replacement));
}

/// Inserts \p Replacement after \p S, leaving the source selected by \S
/// unchanged.
inline ASTEdit insertAfter(RangeSelector S, TextGenerator Replacement) {
  return changeTo(after(std::move(S)), std::move(Replacement));
}

/// Removes the source selected by \p S.
ASTEdit remove(RangeSelector S);

/// Adds an include directive for the given header to the file of `Target`. The
/// particular location specified by `Target` is ignored.
ASTEdit addInclude(RangeSelector Target, StringRef Header,
                   IncludeFormat Format = IncludeFormat::Quoted);

/// Adds an include directive for the given header to the file associated with
/// `RootID`. If `RootID` matches inside a macro expansion, will add the
/// directive to the file in which the macro was expanded (as opposed to the
/// file in which the macro is defined).
inline ASTEdit addInclude(StringRef Header,
                          IncludeFormat Format = IncludeFormat::Quoted) {
  return addInclude(expansion(node(RootID)), Header, Format);
}

// FIXME: If `Metadata` returns an `llvm::Expected<T>` the `AnyGenerator` will
// construct an `llvm::Expected<llvm::Any>` where no error is present but the
// `llvm::Any` holds the error. This is unlikely but potentially surprising.
// Perhaps the `llvm::Expected` should be unwrapped, or perhaps this should be a
// compile-time error. No solution here is perfect.
//
// Note: This function template accepts any type callable with a MatchResult
// rather than a `std::function` because the return-type needs to be deduced. If
// it accepted a `std::function<R(MatchResult)>`, lambdas or other callable
// types would not be able to deduce `R`, and users would be forced to specify
// explicitly the type they intended to return by wrapping the lambda at the
// call-site.
template <typename Callable>
inline ASTEdit withMetadata(ASTEdit Edit, Callable Metadata) {
  Edit.Metadata =
      [Gen = std::move(Metadata)](
          const ast_matchers::MatchFinder::MatchResult &R) -> llvm::Any {
    return Gen(R);
  };

  return Edit;
}

/// Assuming that the inner range is enclosed by the outer range, creates
/// precision edits to remove the parts of the outer range that are not included
/// in the inner range.
inline EditGenerator shrinkTo(RangeSelector outer, RangeSelector inner) {
  return editList({remove(enclose(before(outer), before(inner))),
                   remove(enclose(after(inner), after(outer)))});
}

/// Description of a source-code transformation.
//
// A *rewrite rule* describes a transformation of source code. A simple rule
// contains each of the following components:
//
// * Matcher: the pattern term, expressed as clang matchers (with Transformer
//   extensions).
//
// * Edits: a set of Edits to the source code, described with ASTEdits.
//
// * Explanation: explanation of the rewrite.  This will be displayed to the
//   user, where possible; for example, in clang-tidy diagnostics.
//
// However, rules can also consist of (sub)rules, where the first that matches
// is applied and the rest are ignored.  So, the above components are gathered
// as a `Case` and a rule is a list of cases.
//
// Rule cases have an additional, implicit, component: the parameters. These are
// portions of the pattern which are left unspecified, yet bound in the pattern
// so that we can reference them in the edits.
//
// The \c Transformer class can be used to apply the rewrite rule and obtain the
// corresponding replacements.
struct RewriteRule {
  struct Case {
    ast_matchers::internal::DynTypedMatcher Matcher;
    EditGenerator Edits;
    TextGenerator Explanation;
  };
  // We expect RewriteRules will most commonly include only one case.
  SmallVector<Case, 1> Cases;

  /// DEPRECATED: use `::clang::transformer::RootID` instead.
  static const llvm::StringRef RootID;
};

/// Constructs a simple \c RewriteRule.
RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
                     EditGenerator Edits, TextGenerator Explanation = nullptr);

/// Constructs a \c RewriteRule from multiple `ASTEdit`s.
inline RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
                            llvm::SmallVector<ASTEdit, 1> Edits,
                            TextGenerator Explanation = nullptr) {
  return makeRule(std::move(M), editList(std::move(Edits)),
                  std::move(Explanation));
}

/// Overload of \c makeRule for common case of only one edit.
inline RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
                            ASTEdit Edit,
                            TextGenerator Explanation = nullptr) {
  return makeRule(std::move(M), edit(std::move(Edit)), std::move(Explanation));
}

/// For every case in Rule, adds an include directive for the given header. The
/// common use is assumed to be a rule with only one case. For example, to
/// replace a function call and add headers corresponding to the new code, one
/// could write:
/// \code
///   auto R = makeRule(callExpr(callee(functionDecl(hasName("foo")))),
///            changeTo(cat("bar()")));
///   addInclude(R, "path/to/bar_header.h");
///   addInclude(R, "vector", IncludeFormat::Angled);
/// \endcode
void addInclude(RewriteRule &Rule, llvm::StringRef Header,
                IncludeFormat Format = IncludeFormat::Quoted);

/// Applies the first rule whose pattern matches; other rules are ignored.  If
/// the matchers are independent then order doesn't matter. In that case,
/// `applyFirst` is simply joining the set of rules into one.
//
// `applyFirst` is like an `anyOf` matcher with an edit action attached to each
// of its cases. Anywhere you'd use `anyOf(m1.bind("id1"), m2.bind("id2"))` and
// then dispatch on those ids in your code for control flow, `applyFirst` lifts
// that behavior to the rule level.  So, you can write `applyFirst({makeRule(m1,
// action1), makeRule(m2, action2), ...});`
//
// For example, consider a type `T` with a deterministic serialization function,
// `serialize()`.  For performance reasons, we would like to make it
// non-deterministic.  Therefore, we want to drop the expectation that
// `a.serialize() = b.serialize() iff a = b` (although we'll maintain
// `deserialize(a.serialize()) = a`).
//
// We have three cases to consider (for some equality function, `eq`):
// ```
// eq(a.serialize(), b.serialize()) --> eq(a,b)
// eq(a, b.serialize())             --> eq(deserialize(a), b)
// eq(a.serialize(), b)             --> eq(a, deserialize(b))
// ```
//
// `applyFirst` allows us to specify each independently:
// ```
// auto eq_fun = functionDecl(...);
// auto method_call = cxxMemberCallExpr(...);
//
// auto two_calls = callExpr(callee(eq_fun), hasArgument(0, method_call),
//                           hasArgument(1, method_call));
// auto left_call =
//     callExpr(callee(eq_fun), callExpr(hasArgument(0, method_call)));
// auto right_call =
//     callExpr(callee(eq_fun), callExpr(hasArgument(1, method_call)));
//
// RewriteRule R = applyFirst({makeRule(two_calls, two_calls_action),
//                             makeRule(left_call, left_call_action),
//                             makeRule(right_call, right_call_action)});
// ```
RewriteRule applyFirst(ArrayRef<RewriteRule> Rules);

/// Applies `Rule` to all descendants of the node bound to `NodeId`. `Rule` can
/// refer to nodes bound by the calling rule. `Rule` is not applied to the node
/// itself.
///
/// For example,
/// ```
/// auto InlineX =
///     makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
/// makeRule(functionDecl(hasName("f"), hasBody(stmt().bind("body"))).bind("f"),
///          flatten(
///            changeTo(name("f"), cat("newName")),
///            rewriteDescendants("body", InlineX)));
/// ```
/// Here, we find the function `f`, change its name to `newName` and change all
/// appearances of `x` in its body to `3`.
EditGenerator rewriteDescendants(std::string NodeId, RewriteRule Rule);

/// The following three functions are a low-level part of the RewriteRule
/// API. We expose them for use in implementing the fixtures that interpret
/// RewriteRule, like Transformer and TransfomerTidy, or for more advanced
/// users.
//
// FIXME: These functions are really public, if advanced, elements of the
// RewriteRule API.  Recast them as such.  Or, just declare these functions
// public and well-supported and move them out of `detail`.
namespace detail {
/// The following overload set is a version of `rewriteDescendants` that
/// operates directly on the AST, rather than generating a Transformer
/// combinator. It applies `Rule` to all descendants of `Node`, although not
/// `Node` itself. `Rule` can refer to nodes bound in `Result`.
///
/// For example, assuming that "body" is bound to a function body in MatchResult
/// `Results`, this will produce edits to change all appearances of `x` in that
/// body to `3`.
/// ```
/// auto InlineX =
///     makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3")));
/// const auto *Node = Results.Nodes.getNodeAs<Stmt>("body");
/// auto Edits = rewriteDescendants(*Node, InlineX, Results);
/// ```
/// @{
llvm::Expected<SmallVector<Edit, 1>>
rewriteDescendants(const Decl &Node, RewriteRule Rule,
                   const ast_matchers::MatchFinder::MatchResult &Result);

llvm::Expected<SmallVector<Edit, 1>>
rewriteDescendants(const Stmt &Node, RewriteRule Rule,
                   const ast_matchers::MatchFinder::MatchResult &Result);

llvm::Expected<SmallVector<Edit, 1>>
rewriteDescendants(const TypeLoc &Node, RewriteRule Rule,
                   const ast_matchers::MatchFinder::MatchResult &Result);

llvm::Expected<SmallVector<Edit, 1>>
rewriteDescendants(const DynTypedNode &Node, RewriteRule Rule,
                   const ast_matchers::MatchFinder::MatchResult &Result);
/// @}

/// Builds a single matcher for the rule, covering all of the rule's cases.
/// Only supports Rules whose cases' matchers share the same base "kind"
/// (`Stmt`, `Decl`, etc.)  Deprecated: use `buildMatchers` instead, which
/// supports mixing matchers of different kinds.
ast_matchers::internal::DynTypedMatcher buildMatcher(const RewriteRule &Rule);

/// Builds a set of matchers that cover the rule.
///
/// One matcher is built for each distinct node matcher base kind: Stmt, Decl,
/// etc. Node-matchers for `QualType` and `Type` are not permitted, since such
/// nodes carry no source location information and are therefore not relevant
/// for rewriting. If any such matchers are included, will return an empty
/// vector.
std::vector<ast_matchers::internal::DynTypedMatcher>
buildMatchers(const RewriteRule &Rule);

/// Gets the beginning location of the source matched by a rewrite rule. If the
/// match occurs within a macro expansion, returns the beginning of the
/// expansion point. `Result` must come from the matching of a rewrite rule.
SourceLocation
getRuleMatchLoc(const ast_matchers::MatchFinder::MatchResult &Result);

/// Returns the \c Case of \c Rule that was selected in the match result.
/// Assumes a matcher built with \c buildMatcher.
const RewriteRule::Case &
findSelectedCase(const ast_matchers::MatchFinder::MatchResult &Result,
                 const RewriteRule &Rule);
} // namespace detail
} // namespace transformer
} // namespace clang

#endif // LLVM_CLANG_TOOLING_TRANSFORMER_REWRITE_RULE_H_
