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