]> granicus.if.org Git - clang/commitdiff
clang-format: [JS] Properly set scopes inside template strings.
authorDaniel Jasper <djasper@google.com>
Tue, 31 Jan 2017 13:03:07 +0000 (13:03 +0000)
committerDaniel Jasper <djasper@google.com>
Tue, 31 Jan 2017 13:03:07 +0000 (13:03 +0000)
Before:
  var f = `aaaaaaaaaaaaa:${aaaaaaa
              .aaaaa} aaaaaaaa
           aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa`;

After:
  var f = `aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa
           aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa`;

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

lib/Format/FormatToken.h
lib/Format/TokenAnnotator.cpp
unittests/Format/FormatTestJS.cpp

index b22e4c5d7c471bafc7ba67edfda5ac89f0f9e7dd..c838cfbe1daba3a988bdc284b0d97d0760361a34 100644 (file)
@@ -337,11 +337,15 @@ struct FormatToken {
 
   /// \brief Returns whether \p Tok is ([{ or a template opening <.
   bool opensScope() const {
+    if (is(TT_TemplateString) && TokenText.endswith("${"))
+      return true;
     return isOneOf(tok::l_paren, tok::l_brace, tok::l_square,
                    TT_TemplateOpener);
   }
   /// \brief Returns whether \p Tok is )]} or a template closing >.
   bool closesScope() const {
+    if (is(TT_TemplateString) && TokenText.startswith("}"))
+      return true;
     return isOneOf(tok::r_paren, tok::r_brace, tok::r_square,
                    TT_TemplateCloser);
   }
index e58ca6d803e1b60352f992bb559ea6f5c4be5c9b..2785ca45e70f727acd3834265b65bca064788b50 100644 (file)
@@ -1454,7 +1454,9 @@ public:
 
       // Consume scopes: (), [], <> and {}
       if (Current->opensScope()) {
-        while (Current && !Current->closesScope()) {
+        // In fragment of a JavaScript template string can look like '}..${' and
+        // thus close a scope and open a new one at the same time.
+        while (Current && (!Current->closesScope() || Current->opensScope())) {
           next();
           parse();
         }
index 71821a06499d357170c78f521f1516b1cd5845a9..6cc3bcd16c466aaeabc7c187692e264e8f4257c7 100644 (file)
@@ -1392,6 +1392,13 @@ TEST_F(FormatTestJS, TemplateStrings) {
   // The token stream can contain two string_literals in sequence, but that
   // doesn't mean that they are implicitly concatenated in JavaScript.
   verifyFormat("var f = `aaaa ${a ? 'a' : 'b'}`;");
+
+  // Ensure that scopes are appropriately set around evaluated expressions in
+  // template strings.
+  verifyFormat("var f = `aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa\n"
+               "         aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa`;",
+               "var f = `aaaaaaaaaaaaa:${aaaaaaa.  aaaaa} aaaaaaaa\n"
+               "         aaaaaaaaaaaaa:${  aaaaaaa. aaaaa} aaaaaaaa`;");
 }
 
 TEST_F(FormatTestJS, TemplateStringASI) {