[PATCH] D68227: [clang-format] [PR43372] - clang-format shows replacements in DOS files when no replacement is needed

MyDeveloperDay via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 30 08:04:22 PDT 2019


MyDeveloperDay created this revision.
MyDeveloperDay added reviewers: krasimir, klimek, owenpan, ioeric.
MyDeveloperDay added a project: clang-format.
Herald added a project: clang.
MyDeveloperDay edited the summary of this revision.

This is a patch to fix PR43372 (https://bugs.llvm.org/show_bug.cgi?id=43372) - clang-format can't format file with includes, ( which really keep providing replacements for already sorted headers.)

A similar issue was addressed by @krasimir in D60199: [clang-format] Do not emit replacements while regrouping if Cpp includes are OK <https://reviews.llvm.org/D60199>, however, this seemingly only prevented the issue when the files being formatted did not contain windows line endings (\r\n)

It's possible this is related to https://twitter.com/StephanTLavavej/status/1176722938243895296 given who @STL_MSFT  works for!

As people often used the existence of replacements to determine if a file needs clang-formatting, this is probably pretty important for windows users

There may be a better way of comparing 2 strings and ignoring \r (which appear in both Results and Code), I couldn't choose between this idiom or the copy_if approach, but I'm happy to change it to whatever people consider more performant.


Repository:
  rC Clang

https://reviews.llvm.org/D68227

Files:
  clang/lib/Format/Format.cpp
  clang/unittests/Format/SortImportsTestJava.cpp
  clang/unittests/Format/SortIncludesTest.cpp


Index: clang/unittests/Format/SortIncludesTest.cpp
===================================================================
--- clang/unittests/Format/SortIncludesTest.cpp
+++ clang/unittests/Format/SortIncludesTest.cpp
@@ -653,6 +653,14 @@
   EXPECT_EQ(Code, sort(Code, "input.h", 0));
 }
 
+TEST_F(SortIncludesTest,
+       DoNotOutputReplacementsForSortedBlocksWithRegroupingWindows) {
+  Style.IncludeBlocks = Style.IBS_Regroup;
+  std::string Code = "#include \"b.h\"\r\n"
+                     "\r\n"
+                     "#include <a.h>\r\n";
+  EXPECT_EQ(Code, sort(Code, "input.h", 0));
+}
 
 TEST_F(SortIncludesTest, DoNotRegroupGroupsInGoogleObjCStyle) {
   FmtStyle = getGoogleStyle(FormatStyle::LK_ObjC);
Index: clang/unittests/Format/SortImportsTestJava.cpp
===================================================================
--- clang/unittests/Format/SortImportsTestJava.cpp
+++ clang/unittests/Format/SortImportsTestJava.cpp
@@ -285,6 +285,13 @@
       sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty());
 }
 
+TEST_F(SortImportsTestJava, NoReplacementsForValidImportsWindows) {
+  std::string Code = "import org.a;\r\n"
+                     "import org.b;\r\n";
+  EXPECT_TRUE(
+      sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty());
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -1808,6 +1808,14 @@
   return std::make_pair(CursorIndex, OffsetToEOL);
 }
 
+// Compares two strings but ignores any \r in either strings.
+static bool compareIgnoringCarriageReturns(std::string Result,
+                                           std::string Code) {
+  Result.erase(std::remove(Result.begin(), Result.end(), '\r'), Result.end());
+  Code.erase(std::remove(Code.begin(), Code.end(), '\r'), Code.end());
+  return Result == Code;
+}
+
 // Sorts and deduplicate a block of includes given by 'Includes' alphabetically
 // adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
 // source order.
@@ -1879,7 +1887,8 @@
 
   // If the #includes are out of order, we generate a single replacement fixing
   // the entire range of blocks. Otherwise, no replacement is generated.
-  if (result == Code.substr(IncludesBeginOffset, IncludesBlockSize))
+  if (compareIgnoringCarriageReturns(
+          result, Code.substr(IncludesBeginOffset, IncludesBlockSize)))
     return;
 
   auto Err = Replaces.add(tooling::Replacement(
@@ -2044,7 +2053,8 @@
 
   // If the imports are out of order, we generate a single replacement fixing
   // the entire block. Otherwise, no replacement is generated.
-  if (result == Code.substr(Imports.front().Offset, ImportsBlockSize))
+  if (compareIgnoringCarriageReturns(
+          result, Code.substr(Imports.front().Offset, ImportsBlockSize)))
     return;
 
   auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
@@ -2334,7 +2344,7 @@
 
   auto Env =
       std::make_unique<Environment>(Code, FileName, Ranges, FirstStartColumn,
-                                     NextStartColumn, LastStartColumn);
+                                    NextStartColumn, LastStartColumn);
   llvm::Optional<std::string> CurrentCode = None;
   tooling::Replacements Fixes;
   unsigned Penalty = 0;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D68227.222431.patch
Type: text/x-patch
Size: 3418 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190930/ffbf61ea/attachment.bin>


More information about the cfe-commits mailing list