llvm/clang/unittests/Tooling/TransformerTest.cpp

//===- unittest/Tooling/TransformerTest.cpp -------------------------------===//
//
// 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 "clang/Tooling/Transformer/Transformer.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Tooling/Transformer/RangeSelector.h"
#include "clang/Tooling/Transformer/RewriteRule.h"
#include "clang/Tooling/Transformer/Stencil.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <optional>

usingnamespaceclang;
usingnamespacetooling;
usingnamespaceast_matchers;
namespace {
addInclude;
applyFirst;
before;
cat;
changeTo;
editList;
makeRule;
member;
name;
node;
noEdits;
remove;
rewriteDescendants;
RewriteRule;
RewriteRuleWith;
statement;
ElementsAre;
IsEmpty;
ResultOf;
UnorderedElementsAre;

constexpr char KHeaderContents[] =;

static ast_matchers::internal::Matcher<clang::QualType>
isOrPointsTo(const clang::ast_matchers::DeclarationMatcher &TypeMatcher) {}

static std::string format(StringRef Code) {}

static void compareSnippets(StringRef Expected,
                            const std::optional<std::string> &MaybeActual) {}

// FIXME: consider separating this class into its own file(s).
class ClangRefactoringTestBase : public testing::Test {};

class TransformerTest : public ClangRefactoringTestBase {};

// Given string s, change strlen($s.c_str()) to REPLACED.
static RewriteRuleWith<std::string> ruleStrlenSize() {}

TEST_F(TransformerTest, StrlenSize) {}

// Tests that no change is applied when a match is not expected.
TEST_F(TransformerTest, NoMatch) {}

// Tests replacing an expression.
TEST_F(TransformerTest, Flag) {}

TEST_F(TransformerTest, AddIncludeQuoted) {}

TEST_F(TransformerTest, AddIncludeAngled) {}

TEST_F(TransformerTest, AddIncludeQuotedForRule) {}

TEST_F(TransformerTest, AddIncludeAngledForRule) {}

TEST_F(TransformerTest, NodePartNameNamedDecl) {}

TEST_F(TransformerTest, NodePartNameDeclRef) {}

TEST_F(TransformerTest, NodePartNameDeclRefFailure) {}

TEST_F(TransformerTest, NodePartMember) {}

TEST_F(TransformerTest, NodePartMemberQualified) {}

TEST_F(TransformerTest, NodePartMemberMultiToken) {}

TEST_F(TransformerTest, NoEdits) {}

TEST_F(TransformerTest, NoopEdit) {}

TEST_F(TransformerTest, IfBound2Args) {}

TEST_F(TransformerTest, IfBound3Args) {}

TEST_F(TransformerTest, ShrinkTo) {}

// Rewrite various Stmts inside a Decl.
TEST_F(TransformerTest, RewriteDescendantsDeclChangeStmt) {}

// Rewrite various TypeLocs inside a Decl.
TEST_F(TransformerTest, RewriteDescendantsDeclChangeTypeLoc) {}

TEST_F(TransformerTest, RewriteDescendantsStmt) {}

TEST_F(TransformerTest, RewriteDescendantsStmtWithAdditionalChange) {}

TEST_F(TransformerTest, RewriteDescendantsTypeLoc) {}

TEST_F(TransformerTest, RewriteDescendantsReferToParentBinding) {}

TEST_F(TransformerTest, RewriteDescendantsUnboundNode) {}

TEST_F(TransformerTest, RewriteDescendantsInvalidNodeType) {}

//
// We include one test per typed overload. We don't test extensively since that
// is already covered by the tests above.
//

TEST_F(TransformerTest, RewriteDescendantsTypedStmt) {}

TEST_F(TransformerTest, RewriteDescendantsTypedDecl) {}

TEST_F(TransformerTest, RewriteDescendantsTypedTypeLoc) {}

TEST_F(TransformerTest, RewriteDescendantsTypedDynTyped) {}

TEST_F(TransformerTest, InsertBeforeEdit) {}

TEST_F(TransformerTest, InsertAfterEdit) {}

TEST_F(TransformerTest, RemoveEdit) {}

TEST_F(TransformerTest, WithMetadata) {}

TEST_F(TransformerTest, MultiChange) {}

TEST_F(TransformerTest, EditList) {}

TEST_F(TransformerTest, Flatten) {}

TEST_F(TransformerTest, FlattenWithMixedArgs) {}

TEST_F(TransformerTest, OrderedRuleUnrelated) {}

TEST_F(TransformerTest, OrderedRuleRelated) {}

// Change the order of the rules to get a different result. When `ReplaceF1OrF2`
// comes first, it applies for both uses, so `ReplaceF1` never applies.
TEST_F(TransformerTest, OrderedRuleRelatedSwapped) {}

// Verify that a set of rules whose matchers have different base kinds works
// properly, including that `applyFirst` produces multiple matchers.  We test
// two different kinds of rules: Expr and Decl. We place the Decl rule in the
// middle to test that `buildMatchers` works even when the kinds aren't grouped
// together.
TEST_F(TransformerTest, OrderedRuleMultipleKinds) {}

// Verifies that a rule with a top-level matcher for an implicit node (like
// `implicitCastExpr`) works correctly -- the implicit nodes are not skipped.
TEST_F(TransformerTest, OrderedRuleImplicitMatched) {}

//
// Negative tests (where we expect no transformation to occur).
//

// Tests for a conflict in edits from a single match for a rule.
TEST_F(TransformerTest, TextGeneratorFailure) {}

// Tests for a conflict in edits from a single match for a rule.
TEST_F(TransformerTest, OverlappingEditsInRule) {}

// Tests for a conflict in edits across multiple matches (of the same rule).
TEST_F(TransformerTest, OverlappingEditsMultipleMatches) {}

TEST_F(TransformerTest, ErrorOccurredMatchSkipped) {}

TEST_F(TransformerTest, ImplicitNodes_ConstructorDecl) {}

TEST_F(TransformerTest, ImplicitNodes_RangeFor) {}

TEST_F(TransformerTest, ImplicitNodes_ForStmt) {}

TEST_F(TransformerTest, ImplicitNodes_ForStmt2) {}

TEST_F(TransformerTest, TemplateInstantiation) {}

// Transformation of macro source text when the change encompasses the entirety
// of the expanded text.
TEST_F(TransformerTest, SimpleMacro) {}

// Transformation of macro source text when the change encompasses the entirety
// of the expanded text, for the case of function-style macros.
TEST_F(TransformerTest, FunctionMacro) {}

// Tests that expressions in macro arguments can be rewritten.
TEST_F(TransformerTest, MacroArg) {}

// Tests that expressions in macro arguments can be rewritten, even when the
// macro call occurs inside another macro's definition.
TEST_F(TransformerTest, MacroArgInMacroDef) {}

// Tests the corner case of the identity macro, specifically that it is
// discarded in the rewrite rather than preserved (like PLUS is preserved in the
// previous test).  This behavior is of dubious value (and marked with a FIXME
// in the code), but we test it to verify (and demonstrate) how this case is
// handled.
TEST_F(TransformerTest, IdentityMacro) {}

// Tests that two changes in a single macro expansion do not lead to conflicts
// in applying the changes.
TEST_F(TransformerTest, TwoChangesInOneMacroExpansion) {}

// Tests case where the rule's match spans both source from the macro and its
// arg, with the begin location (the "anchor") being the arg.
TEST_F(TransformerTest, MatchSpansMacroTextButChangeDoesNot) {}

// Tests case where the rule's match spans both source from the macro and its
// arg, with the begin location (the "anchor") being inside the macro.
TEST_F(TransformerTest, MatchSpansMacroTextButChangeDoesNotAnchoredInMacro) {}

// No rewrite is applied when the changed text does not encompass the entirety
// of the expanded text. That is, the edit would have to be applied to the
// macro's definition to succeed and editing the expansion point would not
// suffice.
TEST_F(TransformerTest, NoPartialRewriteOMacroExpansion) {}

// This test handles the corner case where a macro expands within another macro
// to matching code, but that code is an argument to the nested macro call.  A
// simple check of isMacroArgExpansion() vs. isMacroBodyExpansion() will get
// this wrong, and transform the code.
TEST_F(TransformerTest, NoPartialRewriteOfMacroExpansionForMacroArgs) {}

#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
// Verifies that `Type` and `QualType` are not allowed as top-level matchers in
// rules.
TEST(TransformerDeathTest, OrderedRuleTypes) {
  RewriteRule QualTypeRule = makeRule(qualType(), changeTo(cat("Q")));
  EXPECT_DEATH(transformer::detail::buildMatchers(QualTypeRule),
               "Matcher must be.*node matcher");

  RewriteRule TypeRule = makeRule(arrayType(), changeTo(cat("T")));
  EXPECT_DEATH(transformer::detail::buildMatchers(TypeRule),
               "Matcher must be.*node matcher");
}
#endif

// Edits are able to span multiple files; in this case, a header and an
// implementation file.
TEST_F(TransformerTest, MultipleFiles) {}

TEST_F(TransformerTest, AddIncludeMultipleFiles) {}

// A single change set can span multiple files.
TEST_F(TransformerTest, MultiFileEdit) {}

TEST_F(TransformerTest, GeneratesMetadata) {}

TEST_F(TransformerTest, GeneratesMetadataWithNoEdits) {}

TEST_F(TransformerTest, PropagateMetadataErrors) {}

} // namespace