1 | //===- MutationsTest.cpp --------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file tests mutation API for syntax trees. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "clang/Tooling/Syntax/Mutations.h" |
14 | #include "TreeTestBase.h" |
15 | #include "clang/Tooling/Syntax/BuildTree.h" |
16 | |
17 | using namespace clang; |
18 | using namespace clang::syntax; |
19 | |
20 | namespace { |
21 | |
22 | class MutationTest : public SyntaxTreeTest { |
23 | protected: |
24 | using Transformation = std::function<void(const llvm::Annotations & /*Input*/, |
25 | TranslationUnit * /*Root*/)>; |
26 | void CheckTransformation(Transformation Transform, std::string Input, |
27 | std::string Expected) { |
28 | llvm::Annotations Source(Input); |
29 | auto *Root = buildTree(Source.code(), GetParam()); |
30 | |
31 | Transform(Source, Root); |
32 | |
33 | auto Replacements = syntax::computeReplacements(*TM, *Root); |
34 | auto Output = tooling::applyAllReplacements(Source.code(), Replacements); |
35 | if (!Output) { |
36 | ADD_FAILURE() << "could not apply replacements: " |
37 | << llvm::toString(Output.takeError()); |
38 | return; |
39 | } |
40 | |
41 | EXPECT_EQ(Expected, *Output) << "input is:\n" << Input; |
42 | }; |
43 | |
44 | // Removes the selected statement. Input should have exactly one selected |
45 | // range and it should correspond to a single statement. |
46 | Transformation RemoveStatement = [this](const llvm::Annotations &Input, |
47 | TranslationUnit *Root) { |
48 | auto *S = cast<syntax::Statement>(nodeByRange(Input.range(), Root)); |
49 | ASSERT_TRUE(S->canModify()) << "cannot remove a statement" ; |
50 | syntax::removeStatement(*Arena, *TM, S); |
51 | EXPECT_TRUE(S->isDetached()); |
52 | EXPECT_FALSE(S->isOriginal()) |
53 | << "node removed from tree cannot be marked as original" ; |
54 | }; |
55 | }; |
56 | |
57 | INSTANTIATE_TEST_SUITE_P(SyntaxTreeTests, MutationTest, |
58 | ::testing::ValuesIn(allTestClangConfigs()) ); |
59 | |
60 | TEST_P(MutationTest, RemoveStatement_InCompound) { |
61 | CheckTransformation(RemoveStatement, "void test() { [[100+100;]] test(); }" , |
62 | "void test() { test(); }" ); |
63 | } |
64 | |
65 | TEST_P(MutationTest, RemoveStatement_InCompound_Empty) { |
66 | CheckTransformation(RemoveStatement, "void test() { [[;]] }" , |
67 | "void test() { }" ); |
68 | } |
69 | |
70 | TEST_P(MutationTest, RemoveStatement_LeaveEmpty) { |
71 | CheckTransformation(RemoveStatement, "void test() { if (1) [[{}]] else {} }" , |
72 | "void test() { if (1) ; else {} }" ); |
73 | } |
74 | } // namespace |
75 | |