mprobst created this revision. mprobst added a reviewer: krasimir. Herald added a project: clang.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D69971 Files: clang/lib/Format/FormatToken.h clang/lib/Format/FormatTokenLexer.cpp clang/unittests/Format/FormatTestJS.cpp Index: clang/unittests/Format/FormatTestJS.cpp =================================================================== --- clang/unittests/Format/FormatTestJS.cpp +++ clang/unittests/Format/FormatTestJS.cpp @@ -2222,6 +2222,14 @@ verifyFormat("return !!x;\n"); } +TEST_F(FormatTestJS, NullPropagatingOperator) { + verifyFormat("let x = foo?.bar?.baz();\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;"); Index: clang/lib/Format/FormatTokenLexer.cpp =================================================================== --- clang/lib/Format/FormatTokenLexer.cpp +++ clang/lib/Format/FormatTokenLexer.cpp @@ -100,6 +100,10 @@ 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 @@ 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; } Index: clang/lib/Format/FormatToken.h =================================================================== --- clang/lib/Format/FormatToken.h +++ clang/lib/Format/FormatToken.h @@ -60,6 +60,8 @@ TYPE(JsExponentiationEqual) \ TYPE(JsFatArrow) \ TYPE(JsNonNullAssertion) \ + TYPE(JsNullishCoalescingOperator) \ + TYPE(JsNullPropagatingOperator) \ TYPE(JsPrivateIdentifier) \ TYPE(JsTypeColon) \ TYPE(JsTypeOperator) \
Index: clang/unittests/Format/FormatTestJS.cpp =================================================================== --- clang/unittests/Format/FormatTestJS.cpp +++ clang/unittests/Format/FormatTestJS.cpp @@ -2222,6 +2222,14 @@ verifyFormat("return !!x;\n"); } +TEST_F(FormatTestJS, NullPropagatingOperator) { + verifyFormat("let x = foo?.bar?.baz();\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;"); Index: clang/lib/Format/FormatTokenLexer.cpp =================================================================== --- clang/lib/Format/FormatTokenLexer.cpp +++ clang/lib/Format/FormatTokenLexer.cpp @@ -100,6 +100,10 @@ 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 @@ 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; } Index: clang/lib/Format/FormatToken.h =================================================================== --- clang/lib/Format/FormatToken.h +++ clang/lib/Format/FormatToken.h @@ -60,6 +60,8 @@ TYPE(JsExponentiationEqual) \ TYPE(JsFatArrow) \ TYPE(JsNonNullAssertion) \ + TYPE(JsNullishCoalescingOperator) \ + TYPE(JsNullPropagatingOperator) \ TYPE(JsPrivateIdentifier) \ TYPE(JsTypeColon) \ TYPE(JsTypeOperator) \
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits