Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -3717,6 +3717,9 @@ return true; if (Style.isCSharp()) { + if (Left.is(TT_FatArrow) && Right.is(tok::l_brace) && + Style.BraceWrapping.AfterFunction) + return true; if (Right.is(TT_CSharpNamedArgumentColon) || Left.is(TT_CSharpNamedArgumentColon)) return false; Index: clang/lib/Format/UnwrappedLineParser.h =================================================================== --- clang/lib/Format/UnwrappedLineParser.h +++ clang/lib/Format/UnwrappedLineParser.h @@ -138,7 +138,7 @@ // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint void parseCSharpGenericTypeConstraint(); bool tryToParseLambda(); - bool tryToParseCSharpLambda(); + bool tryToParseChildBlock(); bool tryToParseLambdaIntroducer(); bool tryToParsePropertyAccessor(); void tryToParseJSFunction(); Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -1638,19 +1638,9 @@ break; } case tok::equal: - // Fat arrows (=>) have tok::TokenKind tok::equal but TokenType - // TT_FatArrow. They always start an expression or a child block if - // followed by a curly brace. - if (FormatTok->is(TT_FatArrow)) { - nextToken(); - if (FormatTok->is(tok::l_brace)) { - // C# may break after => if the next character is a newline. - if (Style.isCSharp() && Style.BraceWrapping.AfterFunction == true) { - // calling `addUnwrappedLine()` here causes odd parsing errors. - FormatTok->MustBreakBefore = true; - } - parseChildBlock(); - } + if ((Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) && + FormatTok->is(TT_FatArrow)) { + tryToParseChildBlock(); break; } @@ -1726,7 +1716,7 @@ // Try to parse the property accessor: // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties Tokens->setPosition(StoredPosition); - if (!IsTrivialPropertyAccessor && Style.BraceWrapping.AfterFunction == true) + if (!IsTrivialPropertyAccessor && Style.BraceWrapping.AfterFunction) addUnwrappedLine(); nextToken(); do { @@ -1941,18 +1931,15 @@ return true; } -bool UnwrappedLineParser::tryToParseCSharpLambda() { - // Fat arrows (=>) have tok::TokenKind tok::equal but TokenType - // TT_FatArrow. They always start an expression or a child block if - // followed by a curly brace. +bool UnwrappedLineParser::tryToParseChildBlock() { + assert(Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()); + assert(FormatTok->is(TT_FatArrow)); + // Fat arrows (=>) have tok::TokenKind tok::equal but TokenType TT_FatArrow. + // They always start an expression or a child block if followed by a curly + // brace. nextToken(); if (FormatTok->isNot(tok::l_brace)) return false; - // C# may break after => if the next character is a newline. - if (Style.BraceWrapping.AfterFunction) { - // calling `addUnwrappedLine()` here causes odd parsing errors. - FormatTok->MustBreakBefore = true; - } parseChildBlock(); return true; } @@ -1965,24 +1952,15 @@ // FIXME: Once we have an expression parser in the UnwrappedLineParser, // replace this by using parseAssignmentExpression() inside. do { - if (Style.isCSharp() && FormatTok->is(TT_FatArrow)) - if (tryToParseCSharpLambda()) - continue; + if (Style.isCSharp() && FormatTok->is(TT_FatArrow) && + tryToParseChildBlock()) + continue; if (Style.Language == FormatStyle::LK_JavaScript) { if (FormatTok->is(Keywords.kw_function) || FormatTok->startsSequence(Keywords.kw_async, Keywords.kw_function)) { tryToParseJSFunction(); continue; } - if (FormatTok->is(TT_FatArrow)) { - nextToken(); - // Fat arrows can be followed by simple expressions or by child blocks - // in curly braces. - if (FormatTok->is(tok::l_brace)) { - parseChildBlock(); - continue; - } - } if (FormatTok->is(tok::l_brace)) { // Could be a method inside of a braced list `{a() { return 1; }}`. if (tryToParseBracedList()) @@ -1997,12 +1975,6 @@ return !HasError; } switch (FormatTok->Tok.getKind()) { - case tok::caret: - nextToken(); - if (FormatTok->is(tok::l_brace)) { - parseChildBlock(); - } - break; case tok::l_square: if (Style.isCSharp()) parseSquare(); @@ -2094,7 +2066,7 @@ break; case tok::equal: if (Style.isCSharp() && FormatTok->is(TT_FatArrow)) - tryToParseCSharpLambda(); + tryToParseChildBlock(); else nextToken(); break;