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
13using namespace clang;
14
15namespace {
16
17struct 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
24 SourceLocation makeLoc(int Off) { return FileStart.getLocWithOffset(Offset: Off); }
25 CharSourceRange makeCharRange(int StartOff, int EndOff) {
26 return CharSourceRange::getCharRange(B: makeLoc(Off: StartOff), E: makeLoc(Off: EndOff));
27 }
28 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(R: SRange);
36 }
37};
38
39TEST(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(Loc: T.makeLoc(Off: 13), Str: "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
61TEST(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(range: T.CRange, NewStr: "foo");
73 EXPECT_EQ(T.Rewrite.getRewrittenText(T.makeCharRange(42, 47)), "foogc;");
74 T.Rewrite.ReplaceText(range: T.TRange, NewStr: "bar");
75 EXPECT_EQ(T.Rewrite.getRewrittenText(T.makeCharRange(42, 47)), "bar;");
76 T.Rewrite.ReplaceText(range: T.SRange, NewStr: "0");
77 EXPECT_EQ(T.Rewrite.getRewrittenText(T.makeCharRange(42, 47)), "0;");
78}
79
80} // anonymous namespace
81

source code of clang/unittests/Rewrite/RewriterTest.cpp