clang-format: [JS] merge requoting replacements.
authorMartin Probst <martin@probst.io>
Fri, 2 Sep 2016 14:29:48 +0000 (14:29 +0000)
committerMartin Probst <martin@probst.io>
Fri, 2 Sep 2016 14:29:48 +0000 (14:29 +0000)
Summary:
When formatting source code that needs both requoting and reindentation,
merge the replacements to avoid erroring out for conflicting replacements.

Also removes the misleading Replacements parameter from the
TokenAnalyzer API.

Reviewers: djasper

Subscribers: klimek, cfe-commits

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

llvm-svn: 280487

clang/lib/Format/Format.cpp
clang/lib/Format/SortJavaScriptImports.cpp
clang/lib/Format/TokenAnalyzer.cpp
clang/lib/Format/TokenAnalyzer.h
clang/unittests/Format/FormatTestJS.cpp

index 26ef38d..625f855 100644 (file)
@@ -801,14 +801,15 @@ public:
   tooling::Replacements
   analyze(TokenAnnotator &Annotator,
           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
-          FormatTokenLexer &Tokens, tooling::Replacements &Result) override {
+          FormatTokenLexer &Tokens) override {
+    tooling::Replacements RequoteReplaces;
     deriveLocalStyle(AnnotatedLines);
     AffectedRangeMgr.computeAffectedLines(AnnotatedLines.begin(),
                                           AnnotatedLines.end());
 
     if (Style.Language == FormatStyle::LK_JavaScript &&
         Style.JavaScriptQuotes != FormatStyle::JSQS_Leave)
-      requoteJSStringLiteral(AnnotatedLines, Result);
+      requoteJSStringLiteral(AnnotatedLines, RequoteReplaces);
 
     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
       Annotator.calculateFormattingInformation(*AnnotatedLines[i]);
@@ -825,7 +826,7 @@ public:
     UnwrappedLineFormatter(&Indenter, &Whitespaces, Style, Tokens.getKeywords(),
                            IncompleteFormat)
         .format(AnnotatedLines);
-    return Whitespaces.generateReplacements();
+    return RequoteReplaces.merge(Whitespaces.generateReplacements());
   }
 
 private:
@@ -997,7 +998,7 @@ public:
   tooling::Replacements
   analyze(TokenAnnotator &Annotator,
           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
-          FormatTokenLexer &Tokens, tooling::Replacements &Result) override {
+          FormatTokenLexer &Tokens) override {
     // FIXME: in the current implementation the granularity of affected range
     // is an annotated line. However, this is not sufficient. Furthermore,
     // redundant code introduced by replacements does not necessarily
index 2a90e9a..42089c5 100644 (file)
@@ -127,7 +127,7 @@ public:
   tooling::Replacements
   analyze(TokenAnnotator &Annotator,
           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
-          FormatTokenLexer &Tokens, tooling::Replacements &) override {
+          FormatTokenLexer &Tokens) override {
     tooling::Replacements Result;
     AffectedRangeMgr.computeAffectedLines(AnnotatedLines.begin(),
                                           AnnotatedLines.end());
@@ -282,7 +282,6 @@ private:
                         SmallVectorImpl<AnnotatedLine *> &AnnotatedLines) {
     SmallVector<JsModuleReference, 16> References;
     SourceLocation Start;
-    bool FoundLines = false;
     AnnotatedLine *FirstNonImportLine = nullptr;
     bool AnyImportAffected = false;
     for (auto Line : AnnotatedLines) {
@@ -296,7 +295,6 @@ private:
         Start = Line->First->Tok.getLocation();
       if (!Current)
         continue; // Only comments on this line.
-      FoundLines = true;
       JsModuleReference Reference;
       Reference.Range.setBegin(Start);
       if (!parseModuleReference(Keywords, Reference)) {
index 7baba62..d3122ca 100644 (file)
@@ -107,7 +107,7 @@ tooling::Replacements TokenAnalyzer::process() {
     }
 
     tooling::Replacements RunResult =
-        analyze(Annotator, AnnotatedLines, Tokens, Result);
+        analyze(Annotator, AnnotatedLines, Tokens);
 
     DEBUG({
       llvm::dbgs() << "Replacements for run " << Run << ":\n";
index c1aa9c5..aef1ae3 100644 (file)
@@ -87,7 +87,7 @@ protected:
   virtual tooling::Replacements
   analyze(TokenAnnotator &Annotator,
           SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
-          FormatTokenLexer &Tokens, tooling::Replacements &Result) = 0;
+          FormatTokenLexer &Tokens) = 0;
 
   void consumeUnwrappedLine(const UnwrappedLine &TheLine) override;
 
index 6006393..ed22785 100644 (file)
@@ -1334,6 +1334,13 @@ TEST_F(FormatTestJS, RequoteStringsSingle) {
                "let x = \"single\";\n");
 }
 
+TEST_F(FormatTestJS, RequoteAndIndent) {
+  verifyFormat("let x = someVeryLongFunctionThatGoesOnAndOn(\n"
+               "    'double quoted string that needs wrapping');",
+               "let x = someVeryLongFunctionThatGoesOnAndOn("
+               "\"double quoted string that needs wrapping\");");
+}
+
 TEST_F(FormatTestJS, RequoteStringsDouble) {
   FormatStyle DoubleQuotes = getGoogleStyle(FormatStyle::LK_JavaScript);
   DoubleQuotes.JavaScriptQuotes = FormatStyle::JSQS_Double;