r297606 - clang-format: [JS] allow breaking after non-null assertions.

Martin Probst via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 13 02:14:23 PDT 2017


Author: mprobst
Date: Mon Mar 13 04:14:23 2017
New Revision: 297606

URL: http://llvm.org/viewvc/llvm-project?rev=297606&view=rev
Log:
clang-format: [JS] allow breaking after non-null assertions.

Summary:
Previously clang-format would not break after any !. However in TypeScript, ! can be used as a post fix operator for non-nullability:
    x.foo()!.bar()!;

With this change, clang-format will wrap after the ! if it is likely a post-fix non null operator.

Reviewers: djasper

Subscribers: klimek, cfe-commits

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

Modified:
    cfe/trunk/lib/Format/FormatToken.h
    cfe/trunk/lib/Format/TokenAnnotator.cpp
    cfe/trunk/unittests/Format/FormatTestJS.cpp

Modified: cfe/trunk/lib/Format/FormatToken.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=297606&r1=297605&r2=297606&view=diff
==============================================================================
--- cfe/trunk/lib/Format/FormatToken.h (original)
+++ cfe/trunk/lib/Format/FormatToken.h Mon Mar 13 04:14:23 2017
@@ -54,6 +54,7 @@ namespace format {
   TYPE(JavaAnnotation) \
   TYPE(JsComputedPropertyName) \
   TYPE(JsFatArrow) \
+  TYPE(JsNonNullAssertion) \
   TYPE(JsTypeColon) \
   TYPE(JsTypeOperator) \
   TYPE(JsTypeOptionalQuestion) \

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=297606&r1=297605&r2=297606&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Mon Mar 13 04:14:23 2017
@@ -1030,6 +1030,23 @@ private:
       // The token type is already known.
       return;
 
+    if (Style.Language == FormatStyle::LK_JavaScript) {
+      if (Current.is(tok::exclaim)) {
+        if (Current.Previous &&
+            (Current.Previous->isOneOf(tok::identifier, tok::r_paren,
+                                       tok::r_square, tok::r_brace) ||
+             Current.Previous->Tok.isLiteral())) {
+          Current.Type = TT_JsNonNullAssertion;
+          return;
+        }
+        if (Current.Next &&
+            Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) {
+          Current.Type = TT_JsNonNullAssertion;
+          return;
+        }
+      }
+    }
+
     // Line.MightBeFunctionDecl can only be true after the parentheses of a
     // function declaration have been found. In this case, 'Current' is a
     // trailing token of this declaration and thus cannot be a name.
@@ -2284,12 +2301,9 @@ bool TokenAnnotator::spaceRequiredBefore
       // locations that should have whitespace following are identified by the
       // above set of follower tokens.
       return false;
-    // Postfix non-null assertion operator, as in `foo!.bar()`.
-    if (Right.is(tok::exclaim) && (Left.isOneOf(tok::identifier, tok::r_paren,
-                                                tok::r_square, tok::r_brace) ||
-                                   Left.Tok.isLiteral()))
+    if (Right.is(TT_JsNonNullAssertion))
       return false;
-    if (Left.is(tok::exclaim) && Right.is(Keywords.kw_as))
+    if (Left.is(TT_JsNonNullAssertion) && Right.is(Keywords.kw_as))
       return true; // "x! as string"
   } else if (Style.Language == FormatStyle::LK_Java) {
     if (Left.is(tok::r_square) && Right.is(tok::l_brace))
@@ -2545,6 +2559,8 @@ bool TokenAnnotator::canBreakBefore(cons
       return false; // must not break before as in 'x as type' casts
     if (Left.is(Keywords.kw_as))
       return true;
+    if (Left.is(TT_JsNonNullAssertion))
+      return true;
     if (Left.is(Keywords.kw_declare) &&
         Right.isOneOf(Keywords.kw_module, tok::kw_namespace,
                       Keywords.kw_function, tok::kw_class, tok::kw_enum,

Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=297606&r1=297605&r2=297606&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestJS.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestJS.cpp Mon Mar 13 04:14:23 2017
@@ -1714,6 +1714,12 @@ TEST_F(FormatTestJS, NonNullAssertionOpe
   verifyFormat("let x = (foo)!;\n");
   verifyFormat("let x = foo! - 1;\n");
   verifyFormat("let x = {foo: 1}!;\n");
+  verifyFormat(
+      "let x = hello.foo()!\n"
+      "            .foo()!\n"
+      "            .foo()!\n"
+      "            .foo()!;\n",
+      getGoogleJSStyleWithColumns(20));
 }
 
 TEST_F(FormatTestJS, Conditional) {




More information about the cfe-commits mailing list