From a21f0ede7f46e5ebef0c720ce60c53af0306af8d Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Tue, 8 Apr 2014 12:46:38 +0000 Subject: [PATCH] clang-format: Extend AllowShortFunctions.. to only merge inline functions. Before AllowShortFunctionsOnASingleLine could either be true, merging all functions, or false, merging no functions. This patch adds a third value "Inline", which can be used to only merge short functions defined inline in a class, i.e.: void f() { return 42; } class C { void f() { return 42; } }; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205760 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Format/Format.h | 17 +++++++++++--- lib/Format/ContinuationIndenter.cpp | 2 +- lib/Format/Format.cpp | 28 ++++++++++++++++++----- unittests/Format/FormatTest.cpp | 35 ++++++++++++++++++++++++----- 4 files changed, 67 insertions(+), 15 deletions(-) diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index cded911edb..a671845b45 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -163,9 +163,20 @@ struct FormatStyle { /// single line. bool AllowShortLoopsOnASingleLine; - /// \brief If \c true, int f() { return 0; } can be put on a single - /// line. - bool AllowShortFunctionsOnASingleLine; + /// \brief Different styles for merging short functions containing at most one + /// statement. + enum ShortFunctionStyle { + /// \brief Never merge functions into a single line. + SFS_None, + /// \brief Only merge functions defined inside a class. + SFS_Inline, + /// \brief Merge all functions fitting on a single line. + SFS_All, + }; + + /// \brief Dependent on the value, int f() { return 0; } can be put + /// on a single line. + ShortFunctionStyle AllowShortFunctionsOnASingleLine; /// \brief Add a space after \c @property in Objective-C, i.e. use /// @property (readonly) instead of @property(readonly). diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index 5a3dee6387..5317fb33ff 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -145,7 +145,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { getLengthToMatchingParen(Previous) + State.Column > getColumnLimit(State)) return true; if (Current.Type == TT_CtorInitializerColon && - (!Style.AllowShortFunctionsOnASingleLine || + ((Style.AllowShortFunctionsOnASingleLine != FormatStyle::SFS_All) || Style.BreakConstructorInitializersBeforeComma || Style.ColumnLimit != 0)) return true; diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 44116a8f8e..5367106535 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -65,6 +65,16 @@ template <> struct ScalarEnumerationTraits { } }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) { + IO.enumCase(Value, "None", FormatStyle::SFS_None); + IO.enumCase(Value, "false", FormatStyle::SFS_None); + IO.enumCase(Value, "All", FormatStyle::SFS_All); + IO.enumCase(Value, "true", FormatStyle::SFS_All); + IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline); + } +}; + template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) { IO.enumCase(Value, "Attach", FormatStyle::BS_Attach); @@ -251,7 +261,7 @@ FormatStyle getLLVMStyle() { LLVMStyle.AlignEscapedNewlinesLeft = false; LLVMStyle.AlignTrailingComments = true; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; - LLVMStyle.AllowShortFunctionsOnASingleLine = true; + LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; LLVMStyle.AllowShortIfStatementsOnASingleLine = false; LLVMStyle.AllowShortLoopsOnASingleLine = false; LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; @@ -332,7 +342,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { GoogleStyle.MaxEmptyLinesToKeep = 2; GoogleStyle.SpacesInContainerLiterals = false; } else if (Language == FormatStyle::LK_Proto) { - GoogleStyle.AllowShortFunctionsOnASingleLine = false; + GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; } return GoogleStyle; @@ -341,6 +351,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) { FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) { FormatStyle ChromiumStyle = getGoogleStyle(Language); ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false; + ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; ChromiumStyle.AllowShortIfStatementsOnASingleLine = false; ChromiumStyle.AllowShortLoopsOnASingleLine = false; ChromiumStyle.BinPackParameters = false; @@ -523,11 +534,16 @@ public: if (I + 1 == E || I[1]->Type == LT_Invalid) return 0; + // FIXME: TheLine->Level != 0 might or might not be the right check to do. + // If necessary, change to something smarter. + bool MergeShortFunctions = + Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All || + (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline && + TheLine->Level != 0); + if (TheLine->Last->Type == TT_FunctionLBrace && TheLine->First != TheLine->Last) { - return Style.AllowShortFunctionsOnASingleLine - ? tryMergeSimpleBlock(I, E, Limit) - : 0; + return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0; } if (TheLine->Last->is(tok::l_brace)) { return Style.BreakBeforeBraces == FormatStyle::BS_Attach @@ -542,7 +558,7 @@ public: Limit -= 2; unsigned MergedLines = 0; - if (Style.AllowShortFunctionsOnASingleLine) { + if (MergeShortFunctions) { MergedLines = tryMergeSimpleBlock(I + 1, E, Limit); // If we managed to merge the block, count the function header, which is // on a separate line. diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 90e6ff7203..d59ed6c0af 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -5162,7 +5162,7 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { FormatStyle DoNotMerge = getLLVMStyle(); - DoNotMerge.AllowShortFunctionsOnASingleLine = false; + DoNotMerge.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; verifyFormat("void f() { return 42; }"); verifyFormat("void f() {\n" @@ -5219,7 +5219,8 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { format("A()\n:b(0)\n{\n}", NoColumnLimit)); FormatStyle DoNotMergeNoColumnLimit = NoColumnLimit; - DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine = false; + DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine = + FormatStyle::SFS_None; EXPECT_EQ("A()\n" " : b(0) {\n" "}", @@ -5249,6 +5250,19 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { getLLVMStyleWithColumns(23)); } +TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) { + FormatStyle MergeInlineOnly = getLLVMStyle(); + MergeInlineOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; + verifyFormat("class C {\n" + " int f() { return 42; }\n" + "};", + MergeInlineOnly); + verifyFormat("int f() {\n" + " return 42;\n" + "}", + MergeInlineOnly); +} + TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) { // Elaborate type variable declarations. verifyFormat("struct foo a = {bar};\nint n;"); @@ -7537,7 +7551,6 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft); CHECK_PARSE_BOOL(AlignTrailingComments); CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine); - CHECK_PARSE_BOOL(AllowShortFunctionsOnASingleLine); CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine); CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine); CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations); @@ -7590,6 +7603,18 @@ TEST_F(FormatTest, ParsesConfiguration) { CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation); CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always); + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; + CHECK_PARSE("AllowShortFunctionsOnASingleLine: false", + AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None); + CHECK_PARSE("AllowShortFunctionsOnASingleLine: true", + AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All); + CHECK_PARSE("AllowShortFunctionsOnASingleLine: None", + AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None); + CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline", + AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Inline); + CHECK_PARSE("AllowShortFunctionsOnASingleLine: All", + AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All); + Style.SpaceBeforeParens = FormatStyle::SBPO_Always; CHECK_PARSE("SpaceBeforeParens: Never", SpaceBeforeParens, FormatStyle::SBPO_Never); @@ -7943,7 +7968,7 @@ TEST_F(FormatTest, ConstructorInitializerIndentWidth) { "}", Style); - Style.AllowShortFunctionsOnASingleLine = false; + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None; verifyFormat("SomeClass::Constructor()\n" " : a(a)\n" " , b(b)\n" @@ -7954,7 +7979,7 @@ TEST_F(FormatTest, ConstructorInitializerIndentWidth) { Style); Style.ColumnLimit = 80; - Style.AllowShortFunctionsOnASingleLine = true; + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; Style.ConstructorInitializerIndentWidth = 2; verifyFormat("SomeClass::Constructor()\n" " : a(a)\n" -- 2.40.0