1 //===- unittests/Rewrite/RewriterTest.cpp - Rewriter tests ----------------===//
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 #include "clang/Rewrite/Core/Rewriter.h"
10 #include "clang/Tooling/Tooling.h"
11 #include "gtest/gtest.h"
12
13 using namespace clang;
14
15 namespace {
16
17 struct RangeTypeTest {
18 std::unique_ptr<ASTUnit> AST;
19 Rewriter Rewrite;
20 SourceLocation FileStart;
21 CharSourceRange CRange; // covers exact char range
22 CharSourceRange TRange; // extends CRange to whole tokens
23 SourceRange SRange; // different type but behaves like TRange
makeLoc__anon424d0f6b0111::RangeTypeTest24 SourceLocation makeLoc(int Off) { return FileStart.getLocWithOffset(Off); }
makeCharRange__anon424d0f6b0111::RangeTypeTest25 CharSourceRange makeCharRange(int StartOff, int EndOff) {
26 return CharSourceRange::getCharRange(makeLoc(StartOff), makeLoc(EndOff));
27 }
RangeTypeTest__anon424d0f6b0111::RangeTypeTest28 RangeTypeTest(StringRef Code, int StartOff, int EndOff) {
29 AST = tooling::buildASTFromCode(Code);
30 ASTContext &C = AST->getASTContext();
31 Rewrite = Rewriter(C.getSourceManager(), C.getLangOpts());
32 FileStart = AST->getStartOfMainFileID();
33 CRange = makeCharRange(StartOff, EndOff);
34 SRange = CRange.getAsRange();
35 TRange = CharSourceRange::getTokenRange(SRange);
36 }
37 };
38
TEST(Rewriter,GetRewrittenTextRangeTypes)39 TEST(Rewriter, GetRewrittenTextRangeTypes) {
40 // Check that correct text is retrieved for each range type. Check again
41 // after a modification. Ranges remain in terms of the original text but
42 // include the new text.
43 StringRef Code = "int main() { return 0; }";
44 // get char range ^~~ = "ret"
45 // get token range ^~~+++ = "return"
46 // get source range ^~~+++ = "return"
47 // insert "x" ^
48 // get char range ^~~ = "xret"
49 // get token range ^~~+++ = "xreturn"
50 // get source range ^~~+++ = "xreturn"
51 RangeTypeTest T(Code, 13, 16);
52 EXPECT_EQ(T.Rewrite.getRewrittenText(T.CRange), "ret");
53 EXPECT_EQ(T.Rewrite.getRewrittenText(T.TRange), "return");
54 EXPECT_EQ(T.Rewrite.getRewrittenText(T.SRange), "return");
55 T.Rewrite.InsertText(T.makeLoc(13), "x");
56 EXPECT_EQ(T.Rewrite.getRewrittenText(T.CRange), "xret");
57 EXPECT_EQ(T.Rewrite.getRewrittenText(T.TRange), "xreturn");
58 EXPECT_EQ(T.Rewrite.getRewrittenText(T.SRange), "xreturn");
59 }
60
TEST(Rewriter,ReplaceTextRangeTypes)61 TEST(Rewriter, ReplaceTextRangeTypes) {
62 // Check that correct text is replaced for each range type. Ranges remain in
63 // terms of the original text but include the new text.
64 StringRef Code = "int main(int argc, char *argv[]) { return argc; }";
65 // replace char range with "foo" ^~
66 // get ^~~~~ = "foogc;"
67 // replace token range with "bar" ^~++
68 // get ^~~~~ = "bar;"
69 // replace source range with "0" ^~++
70 // get ^~~~~ = "0;"
71 RangeTypeTest T(Code, 42, 44);
72 T.Rewrite.ReplaceText(T.CRange, "foo");
73 EXPECT_EQ(T.Rewrite.getRewrittenText(T.makeCharRange(42, 47)), "foogc;");
74 T.Rewrite.ReplaceText(T.TRange, "bar");
75 EXPECT_EQ(T.Rewrite.getRewrittenText(T.makeCharRange(42, 47)), "bar;");
76 T.Rewrite.ReplaceText(T.SRange, "0");
77 EXPECT_EQ(T.Rewrite.getRewrittenText(T.makeCharRange(42, 47)), "0;");
78 }
79
80 } // anonymous namespace
81