forked from OSchip/llvm-project
[clang-format] Add better support for co-routinues
Responding to a Discord call to help {D113977} and heavily inspired by the unlanded {D34225} add some support to help coroutinues from not being formatted from ```for co_await(auto elt : seq)``` to ``` for co_await(auto elt : seq) ``` Because of the dominance of clang-format in the C++ community, I don't think we should make it the blocker that prevents users from embracing the newer parts of the standard because we butcher the layout of some of the new constucts. Reviewed By: HazardyKnusperkeks, Quuxplusone, ChuanqiXu Differential Revision: https://reviews.llvm.org/D114859
This commit is contained in:
parent
8aabde5a4b
commit
57b95aed2a
|
@ -265,7 +265,7 @@ clang-format
|
|||
space before parentheses. The custom options can be set using
|
||||
``SpaceBeforeParensOptions``.
|
||||
|
||||
- Improved Cpp20 Modules support.
|
||||
- Improved C++20 Modules and Coroutines support.
|
||||
|
||||
libclang
|
||||
--------
|
||||
|
|
|
@ -1004,6 +1004,8 @@ private:
|
|||
if (CurrentToken && CurrentToken->is(Keywords.kw_await))
|
||||
next();
|
||||
}
|
||||
if (Style.isCpp() && CurrentToken && CurrentToken->is(tok::kw_co_await))
|
||||
next();
|
||||
Contexts.back().ColonIsForRangeExpr = true;
|
||||
next();
|
||||
if (!parseParens())
|
||||
|
@ -2952,6 +2954,14 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
|
|||
if (Left.is(tok::kw_auto) && Right.isOneOf(tok::l_paren, tok::l_brace))
|
||||
return false;
|
||||
|
||||
// operator co_await(x)
|
||||
if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && Left.Previous &&
|
||||
Left.Previous->is(tok::kw_operator))
|
||||
return false;
|
||||
// co_await (x), co_yield (x), co_return (x)
|
||||
if (Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return) &&
|
||||
Right.isNot(tok::semi))
|
||||
return true;
|
||||
// requires clause Concept1<T> && Concept2<T>
|
||||
if (Left.is(TT_ConstraintJunctions) && Right.is(tok::identifier))
|
||||
return true;
|
||||
|
|
|
@ -2399,6 +2399,8 @@ void UnwrappedLineParser::parseForOrWhileLoop() {
|
|||
if (Style.Language == FormatStyle::LK_JavaScript &&
|
||||
FormatTok->is(Keywords.kw_await))
|
||||
nextToken();
|
||||
if (Style.isCpp() && FormatTok->is(tok::kw_co_await))
|
||||
nextToken();
|
||||
if (FormatTok->Tok.is(tok::l_paren))
|
||||
parseParens();
|
||||
if (FormatTok->Tok.is(tok::l_brace)) {
|
||||
|
|
|
@ -22724,6 +22724,65 @@ TEST_F(FormatTest, Cpp20ModulesSupport) {
|
|||
verifyFormat("export", Style);
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, CoroutineForCoawait) {
|
||||
FormatStyle Style = getLLVMStyle();
|
||||
verifyFormat("for co_await (auto x : range())\n ;");
|
||||
verifyFormat("for (auto i : arr) {\n"
|
||||
"}",
|
||||
Style);
|
||||
verifyFormat("for co_await (auto i : arr) {\n"
|
||||
"}",
|
||||
Style);
|
||||
verifyFormat("for co_await (auto i : foo(T{})) {\n"
|
||||
"}",
|
||||
Style);
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, CoroutineCoAwait) {
|
||||
verifyFormat("int x = co_await foo();");
|
||||
verifyFormat("int x = (co_await foo());");
|
||||
verifyFormat("co_await (42);");
|
||||
verifyFormat("void operator co_await(int);");
|
||||
verifyFormat("void operator co_await(a);");
|
||||
verifyFormat("co_await a;");
|
||||
verifyFormat("co_await missing_await_resume{};");
|
||||
verifyFormat("co_await a; // comment");
|
||||
verifyFormat("void test0() { co_await a; }");
|
||||
verifyFormat("co_await co_await co_await foo();");
|
||||
verifyFormat("co_await foo().bar();");
|
||||
verifyFormat("co_await [this]() -> Task { co_return x; }");
|
||||
verifyFormat("co_await [this](int a, int b) -> Task { co_return co_await "
|
||||
"foo(); }(x, y);");
|
||||
|
||||
FormatStyle Style = getLLVMStyle();
|
||||
Style.ColumnLimit = 40;
|
||||
verifyFormat("co_await [this](int a, int b) -> Task {\n"
|
||||
" co_return co_await foo();\n"
|
||||
"}(x, y);",
|
||||
Style);
|
||||
verifyFormat("co_await;");
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, CoroutineCoYield) {
|
||||
verifyFormat("int x = co_yield foo();");
|
||||
verifyFormat("int x = (co_yield foo());");
|
||||
verifyFormat("co_yield (42);");
|
||||
verifyFormat("co_yield {42};");
|
||||
verifyFormat("co_yield 42;");
|
||||
verifyFormat("co_yield n++;");
|
||||
verifyFormat("co_yield ++n;");
|
||||
verifyFormat("co_yield;");
|
||||
}
|
||||
|
||||
TEST_F(FormatTest, CoroutineCoReturn) {
|
||||
verifyFormat("co_return (42);");
|
||||
verifyFormat("co_return;");
|
||||
verifyFormat("co_return {};");
|
||||
verifyFormat("co_return x;");
|
||||
verifyFormat("co_return co_await foo();");
|
||||
verifyFormat("co_return co_yield foo();");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace format
|
||||
} // namespace clang
|
||||
|
|
Loading…
Reference in New Issue