r318973 - clang-format: [JS] disable ASI on decorators.

Martin Probst via cfe-commits cfe-commits at lists.llvm.org
Sat Nov 25 01:19:43 PST 2017


Author: mprobst
Date: Sat Nov 25 01:19:42 2017
New Revision: 318973

URL: http://llvm.org/viewvc/llvm-project?rev=318973&view=rev
Log:
clang-format: [JS] disable ASI on decorators.

Summary:
Automatic Semicolon Insertion in clang-format tries to guess if a line
wrap should insert an implicit semicolong. The previous heuristic would
not trigger ASI if a token was immediately preceded by an `@` sign:

    function foo(@Bar  // <-- does not trigger due to preceding @
                baz) {}

However decorators can have arbitrary parameters:

    function foo(@Bar(param, param, param)  // <-- precending @ missed
                baz) {}

While it would be possible to precisely find the matching `@`, just
conversatively disabling ASI for the entire line is simpler, while also
not regressing ASI substatially.

Reviewers: djasper

Subscribers: klimek, cfe-commits

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

Modified:
    cfe/trunk/lib/Format/UnwrappedLineParser.cpp
    cfe/trunk/unittests/Format/FormatTestJS.cpp

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=318973&r1=318972&r2=318973&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Sat Nov 25 01:19:42 2017
@@ -18,6 +18,8 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 
+#include <algorithm>
+
 #define DEBUG_TYPE "format-parser"
 
 namespace clang {
@@ -891,11 +893,14 @@ void UnwrappedLineParser::readTokenWithJ
   bool PreviousMustBeValue = mustBeJSIdentOrValue(Keywords, Previous);
   bool PreviousStartsTemplateExpr =
       Previous->is(TT_TemplateString) && Previous->TokenText.endswith("${");
-  if (PreviousMustBeValue && Line && Line->Tokens.size() > 1) {
-    // If the token before the previous one is an '@', the previous token is an
-    // annotation and can precede another identifier/value.
-    const FormatToken *PrePrevious = std::prev(Line->Tokens.end(), 2)->Tok;
-    if (PrePrevious->is(tok::at))
+  if (PreviousMustBeValue || Previous->is(tok::r_paren)) {
+    // If the line contains an '@' sign, the previous token might be an
+    // annotation, which can precede another identifier/value.
+    bool HasAt = std::find_if(Line->Tokens.begin(), Line->Tokens.end(),
+                              [](UnwrappedLineNode &LineNode) {
+                                return LineNode.Tok->is(tok::at);
+                              }) != Line->Tokens.end();
+    if (HasAt)
       return;
   }
   if (Next->is(tok::exclaim) && PreviousMustBeValue)

Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=318973&r1=318972&r2=318973&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestJS.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestJS.cpp Sat Nov 25 01:19:42 2017
@@ -1197,6 +1197,8 @@ TEST_F(FormatTestJS, AutomaticSemicolonI
                                       "String");
   verifyFormat("function f(@Foo bar) {}", "function f(@Foo\n"
                                           "  bar) {}");
+  verifyFormat("function f(@Foo(Param) bar) {}", "function f(@Foo(Param)\n"
+                                                 "  bar) {}");
   verifyFormat("a = true\n"
                "return 1",
                "a = true\n"
@@ -1564,7 +1566,7 @@ TEST_F(FormatTestJS, EnumDeclarations) {
                "}");
 }
 
-TEST_F(FormatTestJS, MetadataAnnotations) {
+TEST_F(FormatTestJS, Decorators) {
   verifyFormat("@A\nclass C {\n}");
   verifyFormat("@A({arg: 'value'})\nclass C {\n}");
   verifyFormat("@A\n at B\nclass C {\n}");




More information about the cfe-commits mailing list