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 24 SourceLocation makeLoc(int Off) { return FileStart.getLocWithOffset(Off); } 25 CharSourceRange makeCharRange(int StartOff, int EndOff) { 26 return CharSourceRange::getCharRange(makeLoc(StartOff), makeLoc(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(SRange); 36 } 37 }; 38 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 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