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

Martin Probst via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 7 10:30:18 PST 2017


mprobst created this revision.
Herald added a subscriber: klimek.

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.


https://reviews.llvm.org/D30705

Files:
  lib/Format/TokenAnnotator.cpp
  unittests/Format/FormatTestJS.cpp


Index: unittests/Format/FormatTestJS.cpp
===================================================================
--- unittests/Format/FormatTestJS.cpp
+++ unittests/Format/FormatTestJS.cpp
@@ -1679,6 +1679,12 @@
   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) {
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -2204,6 +2204,18 @@
   return true;
 }
 
+// Returns true if Tok is a postfix non-null assertion operator, as in
+// `foo!.bar()`.
+bool isJSNonNullOperator(const FormatToken &Tok) {
+  if (!Tok.Previous)
+    return false;
+  const FormatToken &Previous = *Tok.Previous;
+  return Tok.is(tok::exclaim) &&
+         (Previous.isOneOf(tok::identifier, tok::r_paren, tok::r_square,
+                           tok::r_brace) ||
+          Previous.Tok.isLiteral());
+}
+
 bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
                                          const FormatToken &Right) {
   const FormatToken &Left = *Right.Previous;
@@ -2277,10 +2289,7 @@
       // 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 (isJSNonNullOperator(Right))
       return false;
     if (Left.is(tok::exclaim) && Right.is(Keywords.kw_as))
       return true; // "x! as string"
@@ -2535,6 +2544,8 @@
       return false; // must not break before as in 'x as type' casts
     if (Left.is(Keywords.kw_as))
       return true;
+    if (isJSNonNullOperator(Left))
+      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,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30705.90884.patch
Type: text/x-patch
Size: 2367 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170307/b4eaabef/attachment.bin>


More information about the cfe-commits mailing list