]> granicus.if.org Git - clang/commitdiff
clang-format: [JS] Fix calculation of template string width.
authorDaniel Jasper <djasper@google.com>
Sat, 2 May 2015 08:05:38 +0000 (08:05 +0000)
committerDaniel Jasper <djasper@google.com>
Sat, 2 May 2015 08:05:38 +0000 (08:05 +0000)
OriginalColumn might not be set, so fall back to Location and SourceMgr
in case it is missing. Also initialize end column in case the token is
multi line, but it's the ` token itself that starts the multi line.

Patch by Martin Probst, thank you!

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

lib/Format/Format.cpp
unittests/Format/FormatTestJS.cpp

index 2333b2366a24362d8827f53bfe27131d9c2cb3cb..eabdaca5f3459b6cc1db6f42edafa66676e6b3f4 100644 (file)
@@ -782,7 +782,7 @@ private:
       return false;
 
     FormatToken *EndBacktick = Tokens.back();
-    // Backticks get lexed as tok:unknown tokens. If a template string contains
+    // Backticks get lexed as tok::unknown tokens. If a template string contains
     // a comment start, it gets lexed as a tok::comment, or tok::unknown if
     // unterminated.
     if (!EndBacktick->isOneOf(tok::comment, tok::unknown))
@@ -795,7 +795,8 @@ private:
 
     unsigned TokenCount = 0;
     bool IsMultiline = false;
-    unsigned EndColumnInFirstLine = 0;
+    unsigned EndColumnInFirstLine =
+        EndBacktick->OriginalColumn + EndBacktick->ColumnWidth;
     for (auto I = Tokens.rbegin() + 1, E = Tokens.rend(); I != E; I++) {
       ++TokenCount;
       if (I[0]->NewlinesBefore > 0 || I[0]->IsMultiline)
@@ -833,6 +834,15 @@ private:
       Tokens.back()->TokenText =
           StringRef(Tokens.back()->TokenText.data(),
                     EndOffset - Tokens.back()->TokenText.data());
+
+      unsigned EndOriginalColumn = EndBacktick->OriginalColumn;
+      if (EndOriginalColumn == 0) {
+        SourceLocation Loc = EndBacktick->Tok.getLocation();
+        EndOriginalColumn = SourceMgr.getSpellingColumnNumber(Loc);
+      }
+      // If the ` is further down within the token (e.g. in a comment).
+      EndOriginalColumn += CommentBacktickPos;
+
       if (IsMultiline) {
         // ColumnWidth is from backtick to last token in line.
         // LastLineColumnWidth is 0 to backtick.
@@ -840,12 +850,12 @@ private:
         //     until here`;
         Tokens.back()->ColumnWidth =
             EndColumnInFirstLine - Tokens.back()->OriginalColumn;
-        Tokens.back()->LastLineColumnWidth = EndBacktick->OriginalColumn;
+        Tokens.back()->LastLineColumnWidth = EndOriginalColumn;
         Tokens.back()->IsMultiline = true;
       } else {
         // Token simply spans from start to end, +1 for the ` itself.
         Tokens.back()->ColumnWidth =
-            EndBacktick->OriginalColumn - Tokens.back()->OriginalColumn + 1;
+            EndOriginalColumn - Tokens.back()->OriginalColumn + 1;
       }
       return true;
     }
index e0719ee4fc23de2b6de7e3285e51608d833b7dd9..a7d8dd3effa69b784f84e899a1efc5de3c932c16 100644 (file)
@@ -646,6 +646,12 @@ TEST_F(FormatTestJS, TemplateStrings) {
       "var x =\n    `multi\n  line`;",
       format("var x = `multi\n  line`;", getGoogleJSStyleWithColumns(14 - 1)));
 
+  // Make sure template strings get a proper ColumnWidth assigned, even if they
+  // are first token in line.
+  verifyFormat(
+      "var a = aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
+      "        `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`;");
+
   // Two template strings.
   verifyFormat("var x = `hello` == `hello`;");