mprobst created this revision. mprobst added a reviewer: krasimir. Herald added a project: clang.
clang-format currently treats the nullish coalescing operator `??` like the ternary operator. That causes multiple nullish terms to be each indented relative to the last `??`, as they would in a ternary. The `??` operator is often used in chains though, and as such more similar to other binary operators, such as `||`. So to fix the indent, set its token type to `||`, so it inherits the same treatment. This opens up the question of operator precedence. However, `??` is required to be parenthesized when mixed with `||` and `&&`, so this is not a problem that can come up in syntactically legal code. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D73026 Files: 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 @@ -2294,6 +2294,11 @@ TEST_F(FormatTestJS, NullishCoalescingOperator) { verifyFormat("const val = something ?? 'some other default';\n"); + verifyFormat( + "const val = something ?? otherDefault ??\n" + " evenMore ?? evenMore;\n", + "const val = something ?? otherDefault ?? evenMore ?? evenMore;\n", + getGoogleJSStyleWithColumns(40)); } TEST_F(FormatTestJS, Conditional) { Index: clang/lib/Format/FormatTokenLexer.cpp =================================================================== --- clang/lib/Format/FormatTokenLexer.cpp +++ clang/lib/Format/FormatTokenLexer.cpp @@ -120,8 +120,11 @@ Tokens.back()->Tok.setKind(tok::starequal); return; } - if (tryMergeTokens(JSNullishOperator, TT_JsNullishCoalescingOperator)) + if (tryMergeTokens(JSNullishOperator, TT_JsNullishCoalescingOperator)) { + // Treat like the "||" operator (as opposed to the ternary ?). + Tokens.back()->Tok.setKind(tok::pipepipe); return; + } if (tryMergeTokens(JSNullPropagatingOperator, TT_JsNullPropagatingOperator)) { // Treat like a regular "." access.
Index: clang/unittests/Format/FormatTestJS.cpp =================================================================== --- clang/unittests/Format/FormatTestJS.cpp +++ clang/unittests/Format/FormatTestJS.cpp @@ -2294,6 +2294,11 @@ TEST_F(FormatTestJS, NullishCoalescingOperator) { verifyFormat("const val = something ?? 'some other default';\n"); + verifyFormat( + "const val = something ?? otherDefault ??\n" + " evenMore ?? evenMore;\n", + "const val = something ?? otherDefault ?? evenMore ?? evenMore;\n", + getGoogleJSStyleWithColumns(40)); } TEST_F(FormatTestJS, Conditional) { Index: clang/lib/Format/FormatTokenLexer.cpp =================================================================== --- clang/lib/Format/FormatTokenLexer.cpp +++ clang/lib/Format/FormatTokenLexer.cpp @@ -120,8 +120,11 @@ Tokens.back()->Tok.setKind(tok::starequal); return; } - if (tryMergeTokens(JSNullishOperator, TT_JsNullishCoalescingOperator)) + if (tryMergeTokens(JSNullishOperator, TT_JsNullishCoalescingOperator)) { + // Treat like the "||" operator (as opposed to the ternary ?). + Tokens.back()->Tok.setKind(tok::pipepipe); return; + } if (tryMergeTokens(JSNullPropagatingOperator, TT_JsNullPropagatingOperator)) { // Treat like a regular "." access.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits