]> granicus.if.org Git - clang/commitdiff
clang-format: [JS] fix an assertion failure caused by shrinking sources.
authorMartin Probst <martin@probst.io>
Wed, 8 Jun 2016 14:04:04 +0000 (14:04 +0000)
committerMartin Probst <martin@probst.io>
Wed, 8 Jun 2016 14:04:04 +0000 (14:04 +0000)
Summary:
The JavaScript import sorter has a corner condition that can cause the overall
source text length to shrink. This change circumvents the issue by appending
trailing space in the line after the import blocks to match at least the
previous source code length.

This needs a better long term fix, but this fixes the immediate issue.

Reviewers: alexeagle, djasper

Subscribers: klimek

Differential Revision: http://reviews.llvm.org/D21108

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

lib/Format/SortJavaScriptImports.cpp
unittests/Format/SortImportsTestJS.cpp

index 28c3ae9f6a8bd200f263774ab27d11c72c12e008..fc2a65349272a4f3b78ade0e3cff2ec57c4cfb8e 100644 (file)
@@ -170,12 +170,25 @@ public:
     if (ReferencesInOrder && SymbolsInOrder)
       return Result;
 
+    SourceRange InsertionPoint = References[0].Range;
+    InsertionPoint.setEnd(References[References.size() - 1].Range.getEnd());
+
+    // The loop above might collapse previously existing line breaks between
+    // import blocks, and thus shrink the file. SortIncludes must not shrink
+    // overall source length as there is currently no re-calculation of ranges
+    // after applying source sorting.
+    // This loop just backfills trailing spaces after the imports, which are
+    // harmless and will be stripped by the subsequent formatting pass.
+    // TODO: A better long term fix is to re-calculate Ranges after sorting.
+    unsigned PreviousSize = getSourceText(InsertionPoint).size();
+    while (ReferencesText.size() < PreviousSize) {
+      ReferencesText += " ";
+    }
+
     // Separate references from the main code body of the file.
     if (FirstNonImportLine && FirstNonImportLine->First->NewlinesBefore < 2)
       ReferencesText += "\n";
 
-    SourceRange InsertionPoint = References[0].Range;
-    InsertionPoint.setEnd(References[References.size() - 1].Range.getEnd());
     DEBUG(llvm::dbgs() << "Replacing imports:\n"
                        << getSourceText(InsertionPoint) << "\nwith:\n"
                        << ReferencesText << "\n");
index 140fe4a7466e438a805f087ac3ac988ef21a29e9..17e73b085546b88ab2c2fda6f893b08758e988c6 100644 (file)
@@ -223,6 +223,19 @@ TEST_F(SortImportsTestJS, AffectedRange) {
              24, 30);
 }
 
+TEST_F(SortImportsTestJS, SortingCanShrink) {
+  // Sort excluding a suffix.
+  verifySort("import {B} from 'a';\n"
+             "import {A} from 'b';\n"
+             "\n"
+             "1;",
+             "import {A} from 'b';\n"
+             "\n"
+             "import {B} from 'a';\n"
+             "\n"
+             "1;");
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang