r365258 - [Rewrite] Extend to further accept CharSourceRange

Joel E. Denny via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 5 19:55:06 PDT 2019


Author: jdenny
Date: Fri Jul  5 19:55:06 2019
New Revision: 365258

URL: http://llvm.org/viewvc/llvm-project?rev=365258&view=rev
Log:
[Rewrite] Extend to further accept CharSourceRange

Some Rewrite functions are already overloaded to accept
CharSourceRange, and this extends others in the same manner.  I'm
calling these in code that's not ready to upstream, but I figure they
might be useful to others in the meantime.

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D61467

Added:
    cfe/trunk/unittests/Rewrite/RewriterTest.cpp
Modified:
    cfe/trunk/include/clang/Rewrite/Core/Rewriter.h
    cfe/trunk/lib/Rewrite/Rewriter.cpp
    cfe/trunk/unittests/Rewrite/CMakeLists.txt

Modified: cfe/trunk/include/clang/Rewrite/Core/Rewriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/Core/Rewriter.h?rev=365258&r1=365257&r2=365258&view=diff
==============================================================================
--- cfe/trunk/include/clang/Rewrite/Core/Rewriter.h (original)
+++ cfe/trunk/include/clang/Rewrite/Core/Rewriter.h Fri Jul  5 19:55:06 2019
@@ -84,7 +84,16 @@ public:
   /// in different buffers, this returns an empty string.
   ///
   /// Note that this method is not particularly efficient.
-  std::string getRewrittenText(SourceRange Range) const;
+  std::string getRewrittenText(CharSourceRange Range) const;
+
+  /// getRewrittenText - Return the rewritten form of the text in the specified
+  /// range.  If the start or end of the range was unrewritable or if they are
+  /// in different buffers, this returns an empty string.
+  ///
+  /// Note that this method is not particularly efficient.
+  std::string getRewrittenText(SourceRange Range) const {
+    return getRewrittenText(CharSourceRange::getTokenRange(Range));
+  }
 
   /// InsertText - Insert the specified string at the specified location in the
   /// original buffer.  This method returns true (and does nothing) if the input
@@ -140,6 +149,13 @@ public:
 
   /// ReplaceText - This method replaces a range of characters in the input
   /// buffer with a new string.  This is effectively a combined "remove/insert"
+  /// operation.
+  bool ReplaceText(CharSourceRange range, StringRef NewStr) {
+    return ReplaceText(range.getBegin(), getRangeSize(range), NewStr);
+  }
+
+  /// ReplaceText - This method replaces a range of characters in the input
+  /// buffer with a new string.  This is effectively a combined "remove/insert"
   /// operation.
   bool ReplaceText(SourceRange range, StringRef NewStr) {
     return ReplaceText(range.getBegin(), getRangeSize(range), NewStr);

Modified: cfe/trunk/lib/Rewrite/Rewriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/Rewriter.cpp?rev=365258&r1=365257&r2=365258&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/Rewriter.cpp (original)
+++ cfe/trunk/lib/Rewrite/Rewriter.cpp Fri Jul  5 19:55:06 2019
@@ -170,7 +170,7 @@ int Rewriter::getRangeSize(SourceRange R
 /// in different buffers, this returns an empty string.
 ///
 /// Note that this method is not particularly efficient.
-std::string Rewriter::getRewrittenText(SourceRange Range) const {
+std::string Rewriter::getRewrittenText(CharSourceRange Range) const {
   if (!isRewritable(Range.getBegin()) ||
       !isRewritable(Range.getEnd()))
     return {};
@@ -193,7 +193,9 @@ std::string Rewriter::getRewrittenText(S
 
     // Adjust the end offset to the end of the last token, instead of being the
     // start of the last token.
-    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
+    if (Range.isTokenRange())
+      EndOff +=
+          Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
     return std::string(Ptr, Ptr+EndOff-StartOff);
   }
 
@@ -203,7 +205,8 @@ std::string Rewriter::getRewrittenText(S
 
   // Adjust the end offset to the end of the last token, instead of being the
   // start of the last token.
-  EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
+  if (Range.isTokenRange())
+    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
 
   // Advance the iterators to the right spot, yay for linear time algorithms.
   RewriteBuffer::iterator Start = RB.begin();

Modified: cfe/trunk/unittests/Rewrite/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Rewrite/CMakeLists.txt?rev=365258&r1=365257&r2=365258&view=diff
==============================================================================
--- cfe/trunk/unittests/Rewrite/CMakeLists.txt (original)
+++ cfe/trunk/unittests/Rewrite/CMakeLists.txt Fri Jul  5 19:55:06 2019
@@ -4,8 +4,10 @@ set(LLVM_LINK_COMPONENTS
 
 add_clang_unittest(RewriteTests
   RewriteBufferTest.cpp
+  RewriterTest.cpp
   )
 clang_target_link_libraries(RewriteTests
   PRIVATE
   clangRewrite
+  clangTooling
   )

Added: cfe/trunk/unittests/Rewrite/RewriterTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Rewrite/RewriterTest.cpp?rev=365258&view=auto
==============================================================================
--- cfe/trunk/unittests/Rewrite/RewriterTest.cpp (added)
+++ cfe/trunk/unittests/Rewrite/RewriterTest.cpp Fri Jul  5 19:55:06 2019
@@ -0,0 +1,80 @@
+//===- unittests/Rewrite/RewriterTest.cpp - Rewriter tests ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+
+namespace {
+
+struct RangeTypeTest {
+  std::unique_ptr<ASTUnit> AST;
+  Rewriter Rewrite;
+  SourceLocation FileStart;
+  CharSourceRange CRange; // covers exact char range
+  CharSourceRange TRange; // extends CRange to whole tokens
+  SourceRange SRange;     // different type but behaves like TRange
+  SourceLocation makeLoc(int Off) { return FileStart.getLocWithOffset(Off); }
+  CharSourceRange makeCharRange(int StartOff, int EndOff) {
+    return CharSourceRange::getCharRange(makeLoc(StartOff), makeLoc(EndOff));
+  }
+  RangeTypeTest(StringRef Code, int StartOff, int EndOff) {
+    AST = tooling::buildASTFromCode(Code);
+    ASTContext &C = AST->getASTContext();
+    Rewrite = Rewriter(C.getSourceManager(), C.getLangOpts());
+    FileStart = AST->getStartOfMainFileID();
+    CRange = makeCharRange(StartOff, EndOff);
+    SRange = CRange.getAsRange();
+    TRange = CharSourceRange::getTokenRange(SRange);
+  }
+};
+
+TEST(Rewriter, GetRewrittenTextRangeTypes) {
+  // Check that correct text is retrieved for each range type.  Check again
+  // after a modification.  Ranges remain in terms of the original text but
+  // include the new text.
+  StringRef Code = "int main() { return 0; }";
+  //              get char range ^~~    = "ret"
+  //             get token range ^~~+++ = "return"
+  //            get source range ^~~+++ = "return"
+  //                  insert "x" ^
+  //              get char range ^~~    = "xret"
+  //             get token range ^~~+++ = "xreturn"
+  //            get source range ^~~+++ = "xreturn"
+  RangeTypeTest T(Code, 13, 16);
+  EXPECT_EQ(T.Rewrite.getRewrittenText(T.CRange), "ret");
+  EXPECT_EQ(T.Rewrite.getRewrittenText(T.TRange), "return");
+  EXPECT_EQ(T.Rewrite.getRewrittenText(T.SRange), "return");
+  T.Rewrite.InsertText(T.makeLoc(13), "x");
+  EXPECT_EQ(T.Rewrite.getRewrittenText(T.CRange), "xret");
+  EXPECT_EQ(T.Rewrite.getRewrittenText(T.TRange), "xreturn");
+  EXPECT_EQ(T.Rewrite.getRewrittenText(T.SRange), "xreturn");
+}
+
+TEST(Rewriter, ReplaceTextRangeTypes) {
+  // Check that correct text is replaced for each range type.  Ranges remain in
+  // terms of the original text but include the new text.
+  StringRef Code = "int main(int argc, char *argv[]) { return argc; }";
+  //                            replace char range with "foo" ^~
+  //                                                      get ^~~~~ = "foogc;"
+  //                           replace token range with "bar" ^~++
+  //                                                      get ^~~~~ = "bar;"
+  //                            replace source range with "0" ^~++
+  //                                                      get ^~~~~ = "0;"
+  RangeTypeTest T(Code, 42, 44);
+  T.Rewrite.ReplaceText(T.CRange, "foo");
+  EXPECT_EQ(T.Rewrite.getRewrittenText(T.makeCharRange(42, 47)), "foogc;");
+  T.Rewrite.ReplaceText(T.TRange, "bar");
+  EXPECT_EQ(T.Rewrite.getRewrittenText(T.makeCharRange(42, 47)), "bar;");
+  T.Rewrite.ReplaceText(T.SRange, "0");
+  EXPECT_EQ(T.Rewrite.getRewrittenText(T.makeCharRange(42, 47)), "0;");
+}
+
+} // anonymous namespace




More information about the cfe-commits mailing list