[PATCH] D21026: [clang-format] append newline after code when inserting new headers at the end of the code which does not end with newline.

Eric Liu via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 6 09:07:39 PDT 2016


ioeric created this revision.
ioeric added a reviewer: djasper.
ioeric added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

append newline after code when inserting new headers at the end of the
code which does not end with newline.

http://reviews.llvm.org/D21026

Files:
  lib/Format/Format.cpp
  unittests/Format/CleanupTest.cpp

Index: unittests/Format/CleanupTest.cpp
===================================================================
--- unittests/Format/CleanupTest.cpp
+++ unittests/Format/CleanupTest.cpp
@@ -679,12 +679,12 @@
   EXPECT_EQ(Expected, apply(Code, Replaces));
 }
 
-// FIXME: although this case does not crash, the insertion is wrong. A '\n'
-// should be inserted between the two #includes.
 TEST_F(CleanUpReplacementsTest, NoNewLineAtTheEndOfCode) {
-  std::string Code = "#include <map>";
-  std::string Expected = "#include <map>#include <vector>\n";
-  tooling::Replacements Replaces = {createInsertion("#include <vector>")};
+  std::string Code = "#include \"fix.h\"";
+  std::string Expected =
+      "#include \"fix.h\"\n#include <vector>\n#include \"x.h\"\n";
+  tooling::Replacements Replaces = {createInsertion("#include <vector>"),
+                                    createInsertion("#include \"x.h\"")};
   EXPECT_EQ(Expected, apply(Code, Replaces));
 }
 
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -1476,9 +1476,6 @@
   return AfterComments;
 }
 
-// FIXME: we also need to insert a '\n' at the end of the code if we have an
-// insertion with offset Code.size(), and there is no '\n' at the end of the
-// code.
 // FIXME: do not insert headers into conditional #include blocks, e.g. #includes
 // surrounded by compile condition "#if...".
 // FIXME: do not insert existing headers.
@@ -1560,6 +1557,7 @@
     if (CategoryEndOffsets.find(*I) == CategoryEndOffsets.end())
       CategoryEndOffsets[*I] = CategoryEndOffsets[*std::prev(I)];
 
+  bool NeedNewLineAtEnd = !Code.empty() && Code.back() != '\n';
   for (const auto &R : HeaderInsertions) {
     auto IncludeDirective = R.getReplacementText();
     bool Matched = IncludeRegex.match(IncludeDirective, &Matches);
@@ -1570,6 +1568,19 @@
     int Category =
         Categories.getIncludePriority(IncludeName, /*CheckMainHeader=*/true);
     Offset = CategoryEndOffsets[Category];
+    // When inserting headers at end of the code, also insert a '\n' at the end
+    // of the code if it does not ends with '\n'.
+    // The way of inserting '\n' is a bit of hack since we have no control over
+    // wether header insertions with the same offset (i.e. `Code.size()`) are
+    // inserted after the new line insertion ('\n' would actually be inserted
+    // after other insertions with the same offset). To walk around this,
+    // instead of inserting a '\n' at the end, we replace the last character of
+    // the code with the character itself plus a '\n' character.
+    if (NeedNewLineAtEnd && Offset == Code.size()) {
+      auto End = (Code.substr(Code.size()-1, Code.size()) + "\n").str();
+      Result.insert(tooling::Replacement(FileName, Offset-1, 1, End));
+      NeedNewLineAtEnd = false;
+    }
     std::string NewInclude = !IncludeDirective.endswith("\n")
                                  ? (IncludeDirective + "\n").str()
                                  : IncludeDirective.str();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21026.59736.patch
Type: text/x-patch
Size: 3077 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160606/87d6892a/attachment-0001.bin>


More information about the cfe-commits mailing list