Author: Martin Probst
Date: 2019-11-11T16:35:35+01:00
New Revision: a7638d384983e8e3eb44a2d8c757238efc7096dc

URL: 
https://github.com/llvm/llvm-project/commit/a7638d384983e8e3eb44a2d8c757238efc7096dc
DIFF: 
https://github.com/llvm/llvm-project/commit/a7638d384983e8e3eb44a2d8c757238efc7096dc.diff

LOG: clang-format: [JS] support null operators.

Summary:
JavaScript / TypeScript is adding two new operators: the null
propagating operator `?.` and the nullish coalescing operator `??`.

    const x = foo ?? 'default';
    const z = foo?.bar?.baz;

This change adds support to lex and format both.

Reviewers: krasimir

Subscribers: cfe-commits

Tags: #clang

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

Added: 
    

Modified: 
    clang/lib/Format/FormatToken.h
    clang/lib/Format/FormatTokenLexer.cpp
    clang/unittests/Format/FormatTestJS.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index b11f36559a8b..39498280fb6d 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -60,6 +60,8 @@ namespace format {
   TYPE(JsExponentiationEqual)                                                  
\
   TYPE(JsFatArrow)                                                             
\
   TYPE(JsNonNullAssertion)                                                     
\
+  TYPE(JsNullishCoalescingOperator)                                            
\
+  TYPE(JsNullPropagatingOperator)                                              
\
   TYPE(JsPrivateIdentifier)                                                    
\
   TYPE(JsTypeColon)                                                            
\
   TYPE(JsTypeOperator)                                                         
\

diff  --git a/clang/lib/Format/FormatTokenLexer.cpp 
b/clang/lib/Format/FormatTokenLexer.cpp
index 5d8a77577c0b..ef20ba884fb3 100644
--- a/clang/lib/Format/FormatTokenLexer.cpp
+++ b/clang/lib/Format/FormatTokenLexer.cpp
@@ -100,6 +100,10 @@ void FormatTokenLexer::tryMergePreviousTokens() {
     static const tok::TokenKind JSExponentiation[] = {tok::star, tok::star};
     static const tok::TokenKind JSExponentiationEqual[] = {tok::star,
                                                            tok::starequal};
+    static const tok::TokenKind JSNullPropagatingOperator[] = {tok::question,
+                                                               tok::period};
+    static const tok::TokenKind JSNullishOperator[] = {tok::question,
+                                                       tok::question};
 
     // FIXME: Investigate what token type gives the correct operator priority.
     if (tryMergeTokens(JSIdentity, TT_BinaryOperator))
@@ -116,6 +120,14 @@ void FormatTokenLexer::tryMergePreviousTokens() {
       Tokens.back()->Tok.setKind(tok::starequal);
       return;
     }
+    if (tryMergeTokens(JSNullishOperator, TT_JsNullishCoalescingOperator))
+      return;
+    if (tryMergeTokens(JSNullPropagatingOperator,
+                       TT_JsNullPropagatingOperator)) {
+      // Treat like a regular "." access.
+      Tokens.back()->Tok.setKind(tok::period);
+      return;
+    }
     if (tryMergeJSPrivateIdentifier())
       return;
   }

diff  --git a/clang/unittests/Format/FormatTestJS.cpp 
b/clang/unittests/Format/FormatTestJS.cpp
index ca2093a05cce..30a0b37ef69b 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -2222,6 +2222,16 @@ TEST_F(FormatTestJS, NonNullAssertionOperator) {
   verifyFormat("return !!x;\n");
 }
 
+TEST_F(FormatTestJS, NullPropagatingOperator) {
+  verifyFormat("let x = foo?.bar?.baz();\n");
+  verifyFormat("let x = foo?.(foo);\n");
+  verifyFormat("let x = foo?.['arr'];\n");
+}
+
+TEST_F(FormatTestJS, NullishCoalescingOperator) {
+  verifyFormat("const val = something ?? 'some other default';\n");
+}
+
 TEST_F(FormatTestJS, Conditional) {
   verifyFormat("y = x ? 1 : 2;");
   verifyFormat("x ? 1 : 2;");


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to