Author: owenca Date: 2022-05-12T03:53:08-07:00 New Revision: b6d8c84f28103104a5707091f970d80df423b6c9
URL: https://github.com/llvm/llvm-project/commit/b6d8c84f28103104a5707091f970d80df423b6c9 DIFF: https://github.com/llvm/llvm-project/commit/b6d8c84f28103104a5707091f970d80df423b6c9.diff LOG: [clang-format] Don't remove braces if a 1-statement body would wrap Reimplement the RemoveBracesLLVM feature which handles a single-statement block that would get wrapped. Fixes #53543. Differential Revision: https://reviews.llvm.org/D125137 Added: Modified: clang/lib/Format/UnwrappedLineParser.cpp clang/lib/Format/UnwrappedLineParser.h clang/unittests/Format/FormatTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index f90e8fcb834c7..6ba8edccbb117 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -14,6 +14,7 @@ #include "UnwrappedLineParser.h" #include "FormatToken.h" +#include "TokenAnnotator.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -460,6 +461,7 @@ bool UnwrappedLineParser::precededByCommentOrPPDirective() const { return Previous && Previous->is(tok::comment) && (Previous->IsMultiline || Previous->NewlinesBefore > 0); } + /// \brief Parses a level, that is ???. /// \param HasOpeningBrace If that level is started by an opening brace. /// \param CanContainBracedList If the content can contain (at any level) a @@ -751,6 +753,50 @@ size_t UnwrappedLineParser::computePPHash() const { return h; } +// Checks whether \p ParsedLine might fit on a single line. We must clone the +// tokens of \p ParsedLine before running the token annotator on it so that we +// can restore them afterward. +bool UnwrappedLineParser::mightFitOnOneLine(UnwrappedLine &ParsedLine) const { + const auto ColumnLimit = Style.ColumnLimit; + if (ColumnLimit == 0) + return true; + + auto &Tokens = ParsedLine.Tokens; + assert(!Tokens.empty()); + const auto *LastToken = Tokens.back().Tok; + assert(LastToken); + + SmallVector<UnwrappedLineNode> SavedTokens(Tokens.size()); + + int Index = 0; + for (const auto &Token : Tokens) { + assert(Token.Tok); + auto &SavedToken = SavedTokens[Index++]; + SavedToken.Tok = new FormatToken; + SavedToken.Tok->copyFrom(*Token.Tok); + SavedToken.Children = std::move(Token.Children); + } + + AnnotatedLine Line(ParsedLine); + assert(Line.Last == LastToken); + + TokenAnnotator Annotator(Style, Keywords); + Annotator.annotate(Line); + Annotator.calculateFormattingInformation(Line); + + const int Length = LastToken->TotalLength; + + Index = 0; + for (auto &Token : Tokens) { + const auto &SavedToken = SavedTokens[Index++]; + Token.Tok->copyFrom(*SavedToken.Tok); + Token.Children = std::move(SavedToken.Children); + delete SavedToken.Tok; + } + + return Line.Level * Style.IndentWidth + Length <= ColumnLimit; +} + UnwrappedLineParser::IfStmtKind UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels, bool MunchSemi, bool UnindentWhitesmithsBraces, @@ -813,8 +859,11 @@ UnwrappedLineParser::parseBlock(bool MustBeDeclaration, unsigned AddLevels, const FormatToken *Previous = Tokens->getPreviousToken(); assert(Previous); if (Previous->isNot(tok::r_brace) || Previous->Optional) { - Tok->MatchingParen = FormatTok; - FormatTok->MatchingParen = Tok; + assert(!CurrentLines->empty()); + if (mightFitOnOneLine(CurrentLines->back())) { + Tok->MatchingParen = FormatTok; + FormatTok->MatchingParen = Tok; + } } } diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index 3334b5bad97b4..aea999586ebe3 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -95,6 +95,7 @@ class UnwrappedLineParser { bool parseLevel(bool HasOpeningBrace, bool CanContainBracedList, IfStmtKind *IfKind = nullptr, TokenType NextLBracesType = TT_Unknown); + bool mightFitOnOneLine(UnwrappedLine &Line) const; IfStmtKind parseBlock(bool MustBeDeclaration = false, unsigned AddLevels = 1u, bool MunchSemi = true, bool UnindentWhitesmithsBraces = false, diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 8f9c7215d6193..2a764b68b9129 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -25365,8 +25365,6 @@ TEST_F(FormatTest, RemoveBraces) { "}", Style); - // FIXME: See https://github.com/llvm/llvm-project/issues/53543. -#if 0 Style.ColumnLimit = 65; verifyFormat("if (condition) {\n" @@ -25380,6 +25378,15 @@ TEST_F(FormatTest, RemoveBraces) { Style.ColumnLimit = 20; + verifyFormat("int ab = [](int i) {\n" + " if (i > 0) {\n" + " i = 12345678 -\n" + " i;\n" + " }\n" + " return i;\n" + "};", + Style); + verifyFormat("if (a) {\n" " b = c + // 1 -\n" " d;\n" @@ -25394,9 +25401,6 @@ TEST_F(FormatTest, RemoveBraces) { " b = c >= 0 ? d : e;\n" "}", Style); -#endif - - Style.ColumnLimit = 20; verifyFormat("if (a)\n" " b = c > 0 ? d : e;", _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits