]> granicus.if.org Git - clang/commitdiff
[clang-format] Do not emit replacements if Java imports are OK
authorKrasimir Georgiev <krasimir@google.com>
Wed, 20 Feb 2019 11:44:21 +0000 (11:44 +0000)
committerKrasimir Georgiev <krasimir@google.com>
Wed, 20 Feb 2019 11:44:21 +0000 (11:44 +0000)
Summary:
Currently clang-format would always emit a replacement for a block of Java imports even if it is correctly formatted:
```
% cat /tmp/Aggregator.java
import X;
% clang-format /tmp/Aggregator.java
import X;
% clang-format -output-replacements-xml /tmp/Aggregator.java
<?xml version='1.0'?>
<replacements xml:space='preserve' incomplete_format='false'>
<replacement offset='0' length='9'>import X;</replacement>
</replacements>
%
```
This change makes clang-format not emit replacements in this case. Note that
there is logic to not emit replacements in this case for C++.

Reviewers: ioeric

Reviewed By: ioeric

Subscribers: jdoerfert, cfe-commits

Tags: #clang

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354452 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Format/Format.cpp
unittests/Format/SortImportsTestJava.cpp

index 9575699cf82f49214f9218c482704aa6c1ed4280..9feffeb96cb0b20d469bcd028b04f6282628e682 100644 (file)
@@ -1853,6 +1853,7 @@ static unsigned findJavaImportGroup(const FormatStyle &Style,
 static void sortJavaImports(const FormatStyle &Style,
                             const SmallVectorImpl<JavaImportDirective> &Imports,
                             ArrayRef<tooling::Range> Ranges, StringRef FileName,
+                            StringRef Code,
                             tooling::Replacements &Replaces) {
   unsigned ImportsBeginOffset = Imports.front().Offset;
   unsigned ImportsEndOffset =
@@ -1868,12 +1869,12 @@ static void sortJavaImports(const FormatStyle &Style,
         findJavaImportGroup(Style, Imports[i].Identifier));
   }
   llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
-        // Negating IsStatic to push static imports above non-static imports.
-        return std::make_tuple(!Imports[LHSI].IsStatic, JavaImportGroups[LHSI],
-                               Imports[LHSI].Identifier) <
-               std::make_tuple(!Imports[RHSI].IsStatic, JavaImportGroups[RHSI],
-                               Imports[RHSI].Identifier);
-      });
+    // Negating IsStatic to push static imports above non-static imports.
+    return std::make_tuple(!Imports[LHSI].IsStatic, JavaImportGroups[LHSI],
+                           Imports[LHSI].Identifier) <
+           std::make_tuple(!Imports[RHSI].IsStatic, JavaImportGroups[RHSI],
+                           Imports[RHSI].Identifier);
+  });
 
   // Deduplicate imports.
   Indices.erase(std::unique(Indices.begin(), Indices.end(),
@@ -1902,6 +1903,11 @@ static void sortJavaImports(const FormatStyle &Style,
     CurrentImportGroup = JavaImportGroups[Index];
   }
 
+  // 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))
+    return;
+
   auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
                                                ImportsBlockSize, result));
   // FIXME: better error handling. For now, just skip the replacement for the
@@ -1967,7 +1973,7 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code,
     SearchFrom = Pos + 1;
   }
   if (!ImportsInBlock.empty())
-    sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Replaces);
+    sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces);
   return Replaces;
 }
 
index 3bcf809d961bb4c7e2c35644bc5549cdaff7ea24..fbd349ca47f0f9742bbfca8db9f25779d032b318 100644 (file)
@@ -262,6 +262,14 @@ TEST_F(SortImportsTestJava, NoNewlineAtEnd) {
                  "import org.a;"));
 }
 
+TEST_F(SortImportsTestJava, NoReplacementsForValidImports) {
+  // Identical #includes have led to a failure with an unstable sort.
+  std::string Code = "import org.a;\n"
+                     "import org.b;\n";
+  EXPECT_TRUE(
+      sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty());
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang