[clang] [llvm] [clang-format]: Add `Custom` to `ShortFunctionStyle`; add new AllowShortFunctionsOnASingleLineOptions for granular setup (PR #134337)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Mar 14 20:10:32 PDT 2026
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/134337
>From df25a8bbfd827085265c51a44bedbf38deebbab4 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Sat, 29 Mar 2025 13:54:32 -0700
Subject: [PATCH 01/17] [clang-format]: Add `Custom` to `ShortFunctionStyle`;
add new AllowShortFunctionsOnASingleLineOptions for granular setup
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The current clang-format configuration option AllowShortFunctionsOnASingleLine uses a single enum (ShortFunctionStyle) to control when short function definitions can be merged onto a single line. This enum provides predefined combinations of conditions (e.g., None, Empty only, Inline only, Inline including Empty, All).
This approach has limitations:
1. **Lack of Granularity:** Users cannot specify arbitrary combinations of conditions. For example, a user might want to allow merging for both empty functions and short top-level functions, but not for short functions defined within classes. This is not possible with the current enum options except by choosing All, which might merge more than desired.
2. **Inflexibility:** Adding new conditions for merging (e.g., distinguishing between member functions and constructors, handling lambdas specifically) would require adding many new combined enum values, leading to a combinatorial explosion and making the configuration complex.
3. **Implicit Behavior:** Some options imply others (e.g., Inline implies Empty), which might not always be intuitive or desired.
The goal is to replace this single-choice enum with a more flexible mechanism allowing users to specify a set of conditions that must be met for a short function to be merged onto a single line.
**Proposed Solution**
1. Introduce a new configuration option: AllowShortFunctionsOnSingleLineOptions.
2. This option will accept a list of strings, where each string represents a specific condition allowing merging.
3. **Backward Compatibility:**
- If AllowShortFunctionsOnSingleLineOptions is present in the configuration, it takes precedence.
- If AllowShortFunctionsOnSingleLineOptions is not present, but the old AllowShortFunctionsOnASingleLine is present, the old option should be parsed and mapped to the corresponding new semantics for compatibility.
---
clang/docs/ClangFormatStyleOptions.rst | 64 +++++++++++
clang/include/clang/Format/Format.h | 70 ++++++++++++
clang/lib/Format/Format.cpp | 52 +++++++++
clang/lib/Format/TokenAnnotator.cpp | 7 +-
clang/lib/Format/UnwrappedLineFormatter.cpp | 9 +-
clang/unittests/Format/ConfigParseTest.cpp | 6 ++
clang/unittests/Format/FormatTest.cpp | 111 ++++++++++++++++++++
7 files changed, 310 insertions(+), 9 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 9ecac68ae72bf..167701cf6585d 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1959,6 +1959,70 @@ the configuration (without a prefix: ``Auto``).
};
void f() { bar(); }
+ * ``SFS_Custom`` (in configuration: ``Custom``)
+ Configure merge behavior using AllowShortFunctionsOnASingleLineOptions
+
+
+
+.. _AllowShortFunctionsOnASingleLineOptions:
+
+**AllowShortFunctionsOnASingleLineOptions** (``ShortFunctionMergeFlags``) :versionbadge:`clang-format 21` :ref:`¶ <AllowShortFunctionsOnASingleLineOptions>`
+ Precise control over merging short functions
+
+ If ``AllowShortFunctionsOnASingleLine`` is set to ``Custom``, use this to
+ specify behavior in different situations.
+
+ .. code-block:: yaml
+
+ # Example of usage:
+ AllowShortFunctionsOnASingleLine: Custom
+ AllowShortFunctionsOnASingleLineOptions:
+ Empty: false
+ Inline: true
+ All: false
+
+ Nested configuration flags:
+
+ Precise control over merging short functions
+
+ .. code-block:: c++
+
+ # Should be declared this way:
+ AllowShortFunctionsOnASingleLine: Custom
+ AllowShortFunctionsOnASingleLineOptions:
+ Empty: false
+ Inline: true
+ All: false
+
+ * ``bool Empty`` Only merge empty functions.
+
+ .. code-block:: c++
+
+ void f() {}
+ void f2() {
+ bar2();
+ }
+
+ * ``bool Inline`` Only merge functions defined inside a class.
+
+ .. code-block:: c++
+
+ class Foo {
+ void f() { foo(); }
+ };
+ void f() {
+ foo();
+ }
+ void f() {}
+
+ * ``bool All`` Merge all functions fitting on a single line.
+
+ .. code-block:: c++
+
+ class Foo {
+ void f() { foo(); }
+ };
+ void f() { bar(); }
.. _AllowShortIfStatementsOnASingleLine:
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index fec47a248abb4..96b1ecab04e63 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -871,6 +871,8 @@ struct FormatStyle {
/// void f() { bar(); }
/// \endcode
SFS_All,
+ /// Configure merge behavior using AllowShortFunctionsOnASingleLineOptions
+ SFS_Custom,
};
/// Dependent on the value, ``int f() { return 0; }`` can be put on a
@@ -878,6 +880,72 @@ struct FormatStyle {
/// \version 3.5
ShortFunctionStyle AllowShortFunctionsOnASingleLine;
+ /// Precise control over merging short functions
+ /// \code
+ /// # Should be declared this way:
+ /// AllowShortFunctionsOnASingleLine: Custom
+ /// AllowShortFunctionsOnASingleLineOptions:
+ /// Empty: false
+ /// Inline: true
+ /// All: false
+ /// \endcode
+ struct ShortFunctionMergeFlags {
+ /// Only merge empty functions.
+ /// \code
+ /// void f() {}
+ /// void f2() {
+ /// bar2();
+ /// }
+ /// \endcode
+ bool Empty;
+ /// Only merge functions defined inside a class.
+ /// \code
+ /// class Foo {
+ /// void f() { foo(); }
+ /// };
+ /// void f() {
+ /// foo();
+ /// }
+ /// void f() {}
+ /// \endcode
+ bool Inline;
+ /// Merge all functions fitting on a single line.
+ /// \code
+ /// class Foo {
+ /// void f() { foo(); }
+ /// };
+ /// void f() { bar(); }
+ /// \endcode
+ bool All;
+
+ ShortFunctionMergeFlags() : Empty(false), Inline(false), All(false) {}
+
+ ShortFunctionMergeFlags(bool Empty, bool Inline, bool All)
+ : Empty(Empty), Inline(Inline), All(All) {}
+
+ bool operator==(const ShortFunctionMergeFlags &R) const {
+ return Empty == R.Empty && Inline == R.Inline && All == R.All;
+ }
+ bool operator!=(const ShortFunctionMergeFlags &R) const {
+ return !(*this == R);
+ }
+ };
+
+ /// Precise control over merging short functions
+ ///
+ /// If ``AllowShortFunctionsOnASingleLine`` is set to ``Custom``, use this to
+ /// specify behavior in different situations.
+ /// \code{.yaml}
+ /// # Example of usage:
+ /// AllowShortFunctionsOnASingleLine: Custom
+ /// AllowShortFunctionsOnASingleLineOptions:
+ /// Empty: false
+ /// Inline: true
+ /// All: false
+ /// \endcode
+ /// \version 21
+ ShortFunctionMergeFlags AllowShortFunctionsOnASingleLineOptions;
+
/// Different styles for handling short if statements.
enum ShortIfStyle : int8_t {
/// Never put short ifs on the same line.
@@ -5281,6 +5349,8 @@ struct FormatStyle {
AllowShortEnumsOnASingleLine == R.AllowShortEnumsOnASingleLine &&
AllowShortFunctionsOnASingleLine ==
R.AllowShortFunctionsOnASingleLine &&
+ AllowShortFunctionsOnASingleLineOptions ==
+ R.AllowShortFunctionsOnASingleLineOptions &&
AllowShortIfStatementsOnASingleLine ==
R.AllowShortIfStatementsOnASingleLine &&
AllowShortLambdasOnASingleLine == R.AllowShortLambdasOnASingleLine &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 28aea86139e0d..21f896c6e9cf0 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -622,6 +622,15 @@ template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);
IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);
IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);
+ IO.enumCase(Value, "Custom", FormatStyle::SFS_Custom);
+ }
+};
+
+template <> struct MappingTraits<FormatStyle::ShortFunctionMergeFlags> {
+ static void mapping(IO &IO, FormatStyle::ShortFunctionMergeFlags &Value) {
+ IO.mapOptional("Empty", Value.Empty);
+ IO.mapOptional("Inline", Value.Inline);
+ IO.mapOptional("All", Value.All);
}
};
@@ -982,6 +991,8 @@ template <> struct MappingTraits<FormatStyle> {
Style.AllowShortEnumsOnASingleLine);
IO.mapOptional("AllowShortFunctionsOnASingleLine",
Style.AllowShortFunctionsOnASingleLine);
+ IO.mapOptional("AllowShortFunctionsOnASingleLineOptions",
+ Style.AllowShortFunctionsOnASingleLineOptions);
IO.mapOptional("AllowShortIfStatementsOnASingleLine",
Style.AllowShortIfStatementsOnASingleLine);
IO.mapOptional("AllowShortLambdasOnASingleLine",
@@ -1472,6 +1483,30 @@ static void expandPresetsSpacesInParens(FormatStyle &Expanded) {
Expanded.SpacesInParensOptions = {};
}
+static void expandPresetsShortFunctionsOnSingleLine(FormatStyle &Expanded) {
+ if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Custom)
+ return;
+ // Reset all flags
+ Expanded.AllowShortFunctionsOnASingleLineOptions = {};
+
+ if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None)
+ return;
+
+ if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
+ Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline) {
+ Expanded.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+ }
+
+ if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline ||
+ Expanded.AllowShortFunctionsOnASingleLine ==
+ FormatStyle::SFS_InlineOnly) {
+ Expanded.AllowShortFunctionsOnASingleLineOptions.Inline = true;
+ }
+
+ if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All)
+ Expanded.AllowShortFunctionsOnASingleLineOptions.All = true;
+}
+
FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
FormatStyle LLVMStyle;
LLVMStyle.AccessModifierOffset = -2;
@@ -1501,6 +1536,8 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AllowShortCompoundRequirementOnASingleLine = true;
LLVMStyle.AllowShortEnumsOnASingleLine = true;
LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ LLVMStyle.AllowShortFunctionsOnASingleLineOptions = {};
+ LLVMStyle.AllowShortFunctionsOnASingleLineOptions.All = true;
LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
@@ -1788,6 +1825,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.AlignTrailingComments = {};
GoogleStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Never;
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
+ GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
@@ -1798,6 +1837,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
+ GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
// TODO: still under discussion whether to switch to SLS_All.
GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
@@ -1815,6 +1856,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.SpacesInContainerLiterals = false;
} else if (Language == FormatStyle::LK_Proto) {
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
+ GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
// This affects protocol buffer options specifications and text protos.
// Text protos are currently mostly formatted inside C++ raw string literals
@@ -1834,6 +1877,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
tooling::IncludeStyle::IBS_Preserve;
} else if (Language == FormatStyle::LK_CSharp) {
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
+ GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
GoogleStyle.BreakStringLiterals = false;
GoogleStyle.ColumnLimit = 100;
@@ -1893,6 +1938,8 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
} else {
ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ ChromiumStyle.AllowShortFunctionsOnASingleLineOptions = {};
+ ChromiumStyle.AllowShortFunctionsOnASingleLineOptions.Inline = true;
ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
ChromiumStyle.BinPackParameters = FormatStyle::BPPS_OnePerLine;
@@ -1907,6 +1954,8 @@ FormatStyle getMozillaStyle() {
FormatStyle MozillaStyle = getLLVMStyle();
MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ MozillaStyle.AllowShortFunctionsOnASingleLineOptions = {};
+ MozillaStyle.AllowShortFunctionsOnASingleLineOptions.Inline = true;
MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
FormatStyle::DRTBS_TopLevel;
MozillaStyle.BinPackArguments = false;
@@ -1989,6 +2038,7 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
Style.PenaltyReturnTypeOnItsOwnLine = 1000;
Style.AllowShortEnumsOnASingleLine = false;
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLineOptions = {};
Style.AllowShortCaseLabelsOnASingleLine = false;
Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
Style.AllowShortLoopsOnASingleLine = false;
@@ -2160,6 +2210,7 @@ std::string configurationAsText(const FormatStyle &Style) {
expandPresetsBraceWrapping(NonConstStyle);
expandPresetsSpaceBeforeParens(NonConstStyle);
expandPresetsSpacesInParens(NonConstStyle);
+ expandPresetsShortFunctionsOnSingleLine(NonConstStyle);
Output << NonConstStyle;
return Stream.str();
@@ -3722,6 +3773,7 @@ reformat(const FormatStyle &Style, StringRef Code,
expandPresetsBraceWrapping(Expanded);
expandPresetsSpaceBeforeParens(Expanded);
expandPresetsSpacesInParens(Expanded);
+ expandPresetsShortFunctionsOnSingleLine(Expanded);
Expanded.InsertBraces = false;
Expanded.RemoveBracesLLVM = false;
Expanded.RemoveParentheses = FormatStyle::RPS_Leave;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index d87b3a6088bd8..c058354918140 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5687,11 +5687,10 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
!Left.Children.empty()) {
// Support AllowShortFunctionsOnASingleLine for JavaScript.
- return Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None ||
- Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
+ return (!Style.AllowShortFunctionsOnASingleLineOptions.Inline &&
+ !Style.AllowShortFunctionsOnASingleLineOptions.All) ||
(Left.NestingLevel == 0 && Line.Level == 0 &&
- Style.AllowShortFunctionsOnASingleLine &
- FormatStyle::SFS_InlineOnly);
+ Style.AllowShortFunctionsOnASingleLineOptions.Inline);
}
} else if (Style.Language == FormatStyle::LK_Java) {
if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 000a5105ca407..5be28e895aab6 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -293,15 +293,14 @@ class LineJoiner {
auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine,
TheLine]() {
- if (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All)
+ if (Style.AllowShortFunctionsOnASingleLineOptions.All)
return true;
- if (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty &&
+ if (Style.AllowShortFunctionsOnASingleLineOptions.Empty &&
NextLine.First->is(tok::r_brace)) {
return true;
}
- if (Style.AllowShortFunctionsOnASingleLine &
- FormatStyle::SFS_InlineOnly) {
+ if (Style.AllowShortFunctionsOnASingleLineOptions.Inline) {
// Just checking TheLine->Level != 0 is not enough, because it
// provokes treating functions inside indented namespaces as short.
if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
@@ -551,7 +550,7 @@ class LineJoiner {
unsigned MergedLines = 0;
if (MergeShortFunctions ||
- (Style.AllowShortFunctionsOnASingleLine >= FormatStyle::SFS_Empty &&
+ (Style.AllowShortFunctionsOnASingleLineOptions.Empty &&
NextLine.First == NextLine.Last && I + 2 != E &&
I[2]->First->is(tok::r_brace))) {
MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 287191d04d885..54e484fcbe4cd 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -256,6 +256,9 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
+ CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Empty);
+ CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Inline);
+ CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, All);
}
#undef CHECK_PARSE_BOOL
@@ -620,6 +623,9 @@ TEST(ConfigParseTest, ParsesConfiguration) {
AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Empty);
CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: Custom",
+ AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Custom);
+
// For backward compatibility:
CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 0b90bd360b758..868d4e375b953 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15120,6 +15120,117 @@ TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
MergeInlineOnly);
}
+TEST_F(FormatTest, CustomShortFunctionOptions) {
+ FormatStyle CustomEmpty = getLLVMStyle();
+ CustomEmpty.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
+ CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+ CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Inline = false;
+ CustomEmpty.AllowShortFunctionsOnASingleLineOptions.All = false;
+
+ // Empty functions should be on a single line
+ verifyFormat("int f() {}", CustomEmpty);
+ verifyFormat("class C {\n"
+ " int f() {}\n"
+ "};",
+ CustomEmpty);
+
+ // Non-empty functions should be multi-line
+ verifyFormat("int f() {\n"
+ " return 42;\n"
+ "}",
+ CustomEmpty);
+ verifyFormat("class C {\n"
+ " int f() {\n"
+ " return 42;\n"
+ " }\n"
+ "};",
+ CustomEmpty);
+
+ // Test with AfterFunction = true
+ CustomEmpty.BreakBeforeBraces = FormatStyle::BS_Custom;
+ CustomEmpty.BraceWrapping.AfterFunction = true;
+ verifyFormat("int f() {}", CustomEmpty);
+ verifyFormat("int g()\n"
+ "{\n"
+ " return 42;\n"
+ "}",
+ CustomEmpty);
+
+ // Test with Inline = true, All = false
+ FormatStyle CustomInline = getLLVMStyle();
+ CustomInline.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
+ CustomInline.AllowShortFunctionsOnASingleLineOptions.Empty = false;
+ CustomInline.AllowShortFunctionsOnASingleLineOptions.Inline = true;
+ CustomInline.AllowShortFunctionsOnASingleLineOptions.All = false;
+
+ verifyFormat("class C {\n"
+ " int f() {}\n"
+ "};",
+ CustomInline);
+
+ // Non-empty inline functions should be single-line
+ verifyFormat("class C {\n"
+ " int f() { return 42; }\n"
+ "};",
+ CustomInline);
+
+ // Non-inline functions should be multi-line
+ verifyFormat("int f() {\n"
+ " return 42;\n"
+ "}",
+ CustomInline);
+ verifyFormat("int g() {\n"
+ "}",
+ CustomInline);
+
+ // Test with All = true
+ FormatStyle CustomAll = getLLVMStyle();
+ CustomAll.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
+ CustomAll.AllowShortFunctionsOnASingleLineOptions.Empty = false;
+ CustomAll.AllowShortFunctionsOnASingleLineOptions.Inline = false;
+ CustomAll.AllowShortFunctionsOnASingleLineOptions.All = true;
+
+ // All functions should be on a single line if they fit
+ verifyFormat("int f() { return 42; }", CustomAll);
+ verifyFormat("int g() { return f() + h(); }", CustomAll);
+ verifyFormat("class C {\n"
+ " int f() { return 42; }\n"
+ "};",
+ CustomAll);
+
+ verifyFormat("int f() {}", CustomAll);
+ verifyFormat("class C {\n"
+ " int f() {}\n"
+ "};",
+ CustomAll);
+
+ // Test various combinations
+ FormatStyle CustomMixed = getLLVMStyle();
+ CustomMixed.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
+ CustomMixed.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+ CustomMixed.AllowShortFunctionsOnASingleLineOptions.Inline = true;
+ CustomMixed.AllowShortFunctionsOnASingleLineOptions.All = false;
+
+ // Empty functions should be on a single line
+ verifyFormat("int f() {}", CustomMixed);
+ verifyFormat("class C {\n"
+ " int f() {}\n"
+ "};",
+ CustomMixed);
+
+ // Inline non-empty functions should be on a single line
+ verifyFormat("class C {\n"
+ " int f() { return 42; }\n"
+ "};",
+ CustomMixed);
+
+ // Non-inline non-empty functions should be multi-line
+ verifyFormat("int f() {\n"
+ " return 42;\n"
+ "}",
+ CustomMixed);
+}
+
TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
FormatStyle MergeInlineOnly = getLLVMStyle();
MergeInlineOnly.AllowShortFunctionsOnASingleLine =
>From e9e4e92afca915bfeba3fac0227930a99a5daa34 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Fri, 4 Apr 2025 18:20:28 -0700
Subject: [PATCH 02/17] PR-134337: fixed PR comments
---
clang/docs/ClangFormatStyleOptions.rst | 11 +++++++----
clang/include/clang/Format/Format.h | 17 ++++++++++-------
clang/lib/Format/Format.cpp | 6 +++---
clang/lib/Format/TokenAnnotator.cpp | 2 +-
clang/lib/Format/UnwrappedLineFormatter.cpp | 2 +-
clang/unittests/Format/ConfigParseTest.cpp | 2 +-
clang/unittests/Format/FormatTest.cpp | 11 +++++++----
7 files changed, 30 insertions(+), 21 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 167701cf6585d..c0529dd138f59 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1994,7 +1994,7 @@ the configuration (without a prefix: ``Auto``).
Inline: true
All: false
- * ``bool Empty`` Only merge empty functions.
+ * ``bool Empty`` Merge top-level empty functions.
.. code-block:: c++
@@ -2002,20 +2002,23 @@ the configuration (without a prefix: ``Auto``).
void f2() {
bar2();
}
+ void f3() { /* comment */ }
- * ``bool Inline`` Only merge functions defined inside a class.
+ * ``bool Inline`` Merge functions defined inside a class.
.. code-block:: c++
class Foo {
void f() { foo(); }
+ void g() {}
};
void f() {
foo();
}
- void f() {}
+ void f() {
+ }
- * ``bool All`` Merge all functions fitting on a single line.
+ * ``bool Other`` Merge all functions fitting on a single line.
.. code-block:: c++
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 96b1ecab04e63..971b978adc2c7 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -890,23 +890,26 @@ struct FormatStyle {
/// All: false
/// \endcode
struct ShortFunctionMergeFlags {
- /// Only merge empty functions.
+ /// Merge top-level empty functions.
/// \code
/// void f() {}
/// void f2() {
/// bar2();
/// }
+ /// void f3() { /* comment */ }
/// \endcode
bool Empty;
- /// Only merge functions defined inside a class.
+ /// Merge functions defined inside a class.
/// \code
/// class Foo {
/// void f() { foo(); }
+ /// void g() {}
/// };
/// void f() {
/// foo();
/// }
- /// void f() {}
+ /// void f() {
+ /// }
/// \endcode
bool Inline;
/// Merge all functions fitting on a single line.
@@ -916,15 +919,15 @@ struct FormatStyle {
/// };
/// void f() { bar(); }
/// \endcode
- bool All;
+ bool Other;
- ShortFunctionMergeFlags() : Empty(false), Inline(false), All(false) {}
+ ShortFunctionMergeFlags() : Empty(false), Inline(false), Other(false) {}
ShortFunctionMergeFlags(bool Empty, bool Inline, bool All)
- : Empty(Empty), Inline(Inline), All(All) {}
+ : Empty(Empty), Inline(Inline), Other(All) {}
bool operator==(const ShortFunctionMergeFlags &R) const {
- return Empty == R.Empty && Inline == R.Inline && All == R.All;
+ return Empty == R.Empty && Inline == R.Inline && Other == R.Other;
}
bool operator!=(const ShortFunctionMergeFlags &R) const {
return !(*this == R);
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 21f896c6e9cf0..aff38f56f05e3 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -630,7 +630,7 @@ template <> struct MappingTraits<FormatStyle::ShortFunctionMergeFlags> {
static void mapping(IO &IO, FormatStyle::ShortFunctionMergeFlags &Value) {
IO.mapOptional("Empty", Value.Empty);
IO.mapOptional("Inline", Value.Inline);
- IO.mapOptional("All", Value.All);
+ IO.mapOptional("Other", Value.Other);
}
};
@@ -1504,7 +1504,7 @@ static void expandPresetsShortFunctionsOnSingleLine(FormatStyle &Expanded) {
}
if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All)
- Expanded.AllowShortFunctionsOnASingleLineOptions.All = true;
+ Expanded.AllowShortFunctionsOnASingleLineOptions.Other = true;
}
FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
@@ -1537,7 +1537,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AllowShortEnumsOnASingleLine = true;
LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
LLVMStyle.AllowShortFunctionsOnASingleLineOptions = {};
- LLVMStyle.AllowShortFunctionsOnASingleLineOptions.All = true;
+ LLVMStyle.AllowShortFunctionsOnASingleLineOptions.Other = true;
LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index c058354918140..cdf46f65e8b52 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5688,7 +5688,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
!Left.Children.empty()) {
// Support AllowShortFunctionsOnASingleLine for JavaScript.
return (!Style.AllowShortFunctionsOnASingleLineOptions.Inline &&
- !Style.AllowShortFunctionsOnASingleLineOptions.All) ||
+ !Style.AllowShortFunctionsOnASingleLineOptions.Other) ||
(Left.NestingLevel == 0 && Line.Level == 0 &&
Style.AllowShortFunctionsOnASingleLineOptions.Inline);
}
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 5be28e895aab6..6f30bbc8a9e5f 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -293,7 +293,7 @@ class LineJoiner {
auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine,
TheLine]() {
- if (Style.AllowShortFunctionsOnASingleLineOptions.All)
+ if (Style.AllowShortFunctionsOnASingleLineOptions.Other)
return true;
if (Style.AllowShortFunctionsOnASingleLineOptions.Empty &&
NextLine.First->is(tok::r_brace)) {
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 54e484fcbe4cd..16ab406c9cade 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -258,7 +258,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Empty);
CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Inline);
- CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, All);
+ CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Other);
}
#undef CHECK_PARSE_BOOL
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 868d4e375b953..79ee1230eb6a7 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15125,7 +15125,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
CustomEmpty.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Empty = true;
CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Inline = false;
- CustomEmpty.AllowShortFunctionsOnASingleLineOptions.All = false;
+ CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Other = false;
// Empty functions should be on a single line
verifyFormat("int f() {}", CustomEmpty);
@@ -15146,6 +15146,9 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
"};",
CustomEmpty);
+ // test with comment
+ verifyFormat("void f3() { /* comment */ }", CustomEmpty);
+
// Test with AfterFunction = true
CustomEmpty.BreakBeforeBraces = FormatStyle::BS_Custom;
CustomEmpty.BraceWrapping.AfterFunction = true;
@@ -15161,7 +15164,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
CustomInline.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
CustomInline.AllowShortFunctionsOnASingleLineOptions.Empty = false;
CustomInline.AllowShortFunctionsOnASingleLineOptions.Inline = true;
- CustomInline.AllowShortFunctionsOnASingleLineOptions.All = false;
+ CustomInline.AllowShortFunctionsOnASingleLineOptions.Other = false;
verifyFormat("class C {\n"
" int f() {}\n"
@@ -15188,7 +15191,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
CustomAll.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
CustomAll.AllowShortFunctionsOnASingleLineOptions.Empty = false;
CustomAll.AllowShortFunctionsOnASingleLineOptions.Inline = false;
- CustomAll.AllowShortFunctionsOnASingleLineOptions.All = true;
+ CustomAll.AllowShortFunctionsOnASingleLineOptions.Other = true;
// All functions should be on a single line if they fit
verifyFormat("int f() { return 42; }", CustomAll);
@@ -15209,7 +15212,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
CustomMixed.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
CustomMixed.AllowShortFunctionsOnASingleLineOptions.Empty = true;
CustomMixed.AllowShortFunctionsOnASingleLineOptions.Inline = true;
- CustomMixed.AllowShortFunctionsOnASingleLineOptions.All = false;
+ CustomMixed.AllowShortFunctionsOnASingleLineOptions.Other = false;
// Empty functions should be on a single line
verifyFormat("int f() {}", CustomMixed);
>From b1fd41217c49400248780ba6fb7a2ac0a355937c Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Mon, 7 Apr 2025 21:05:17 -0700
Subject: [PATCH 03/17] Updated configuration with new suggestion - reuse
existing option
---
clang/docs/ClangFormatStyleOptions.rst | 51 ++----
clang/include/clang/Format/Format.h | 152 ++++++++----------
clang/lib/Format/Format.cpp | 120 +++++++-------
clang/lib/Format/TokenAnnotator.cpp | 7 +-
clang/lib/Format/UnwrappedLineFormatter.cpp | 8 +-
clang/unittests/Format/ConfigParseTest.cpp | 38 +++--
.../Format/DefinitionBlockSeparatorTest.cpp | 4 +-
clang/unittests/Format/FormatTest.cpp | 124 +++++++++-----
clang/unittests/Format/FormatTestCSharp.cpp | 5 +-
clang/unittests/Format/FormatTestJS.cpp | 27 +++-
clang/unittests/Format/FormatTestJava.cpp | 5 +-
11 files changed, 289 insertions(+), 252 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index c0529dd138f59..6f3b9f798093f 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1905,12 +1905,16 @@ the configuration (without a prefix: ``Auto``).
Dependent on the value, ``int f() { return 0; }`` can be put on a
single line.
- Possible values:
+ Nested configuration flags:
+
+ Different styles for merging short functions containing at most one
+ statement.
- * ``SFS_None`` (in configuration: ``None``)
+ They can be read as a whole for compatibility. The choices are:
+ * ``None``
Never merge functions into a single line.
- * ``SFS_InlineOnly`` (in configuration: ``InlineOnly``)
+ * ``InlineOnly``
Only merge functions defined inside a class. Same as ``inline``,
except it does not implies ``empty``: i.e. top level empty functions
are not merged either.
@@ -1926,7 +1930,7 @@ the configuration (without a prefix: ``Auto``).
void f() {
}
- * ``SFS_Empty`` (in configuration: ``Empty``)
+ * ``Empty``
Only merge empty functions.
.. code-block:: c++
@@ -1936,7 +1940,7 @@ the configuration (without a prefix: ``Auto``).
bar2();
}
- * ``SFS_Inline`` (in configuration: ``Inline``)
+ * ``Inline``
Only merge functions defined inside a class. Implies ``empty``.
.. code-block:: c++
@@ -1949,7 +1953,7 @@ the configuration (without a prefix: ``Auto``).
}
void f() {}
- * ``SFS_All`` (in configuration: ``All``)
+ * ``All``
Merge all functions fitting on a single line.
.. code-block:: c++
@@ -1959,37 +1963,15 @@ the configuration (without a prefix: ``Auto``).
};
void f() { bar(); }
- * ``SFS_Custom`` (in configuration: ``Custom``)
- Configure merge behavior using AllowShortFunctionsOnASingleLineOptions
-
+ Also can be specified as a nested configuration flag:
-
-.. _AllowShortFunctionsOnASingleLineOptions:
-
-**AllowShortFunctionsOnASingleLineOptions** (``ShortFunctionMergeFlags``) :versionbadge:`clang-format 21` :ref:`¶ <AllowShortFunctionsOnASingleLineOptions>`
- Precise control over merging short functions
-
- If ``AllowShortFunctionsOnASingleLine`` is set to ``Custom``, use this to
- specify behavior in different situations.
-
- .. code-block:: yaml
+ .. code-block:: c++
# Example of usage:
- AllowShortFunctionsOnASingleLine: Custom
- AllowShortFunctionsOnASingleLineOptions:
- Empty: false
- Inline: true
- All: false
-
- Nested configuration flags:
-
- Precise control over merging short functions
+ AllowShortFunctionsOnASingleLine: InlineOnly
- .. code-block:: c++
-
- # Should be declared this way:
- AllowShortFunctionsOnASingleLine: Custom
- AllowShortFunctionsOnASingleLineOptions:
+ # or more granular control:
+ AllowShortFunctionsOnASingleLine:
Empty: false
Inline: true
All: false
@@ -2018,7 +2000,8 @@ the configuration (without a prefix: ``Auto``).
void f() {
}
- * ``bool Other`` Merge all functions fitting on a single line.
+ * ``bool Other`` Merge all functions fitting on a single line. Please note that this
+ control does not include Empty
.. code-block:: c++
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 971b978adc2c7..2278bf3966296 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -827,69 +827,68 @@ struct FormatStyle {
/// Different styles for merging short functions containing at most one
/// statement.
- enum ShortFunctionStyle : int8_t {
- /// Never merge functions into a single line.
- SFS_None,
- /// Only merge functions defined inside a class. Same as ``inline``,
- /// except it does not implies ``empty``: i.e. top level empty functions
- /// are not merged either.
- /// \code
- /// class Foo {
- /// void f() { foo(); }
- /// };
- /// void f() {
- /// foo();
- /// }
- /// void f() {
- /// }
- /// \endcode
- SFS_InlineOnly,
- /// Only merge empty functions.
- /// \code
- /// void f() {}
- /// void f2() {
- /// bar2();
- /// }
- /// \endcode
- SFS_Empty,
- /// Only merge functions defined inside a class. Implies ``empty``.
- /// \code
- /// class Foo {
- /// void f() { foo(); }
- /// };
- /// void f() {
- /// foo();
- /// }
- /// void f() {}
- /// \endcode
- SFS_Inline,
- /// Merge all functions fitting on a single line.
- /// \code
- /// class Foo {
- /// void f() { foo(); }
- /// };
- /// void f() { bar(); }
- /// \endcode
- SFS_All,
- /// Configure merge behavior using AllowShortFunctionsOnASingleLineOptions
- SFS_Custom,
- };
-
- /// Dependent on the value, ``int f() { return 0; }`` can be put on a
- /// single line.
- /// \version 3.5
- ShortFunctionStyle AllowShortFunctionsOnASingleLine;
-
- /// Precise control over merging short functions
+ ///
+ /// They can be read as a whole for compatibility. The choices are:
+ /// * ``None``
+ /// Never merge functions into a single line.
+ ///
+ /// * ``InlineOnly``
+ /// Only merge functions defined inside a class. Same as ``inline``,
+ /// except it does not implies ``empty``: i.e. top level empty functions
+ /// are not merged either.
+ /// \code
+ /// class Foo {
+ /// void f() { foo(); }
+ /// };
+ /// void f() {
+ /// foo();
+ /// }
+ /// void f() {
+ /// }
+ /// \endcode
+ ///
+ /// * ``Empty``
+ /// Only merge empty functions.
+ /// \code
+ /// void f() {}
+ /// void f2() {
+ /// bar2();
+ /// }
+ /// \endcode
+ ///
+ /// * ``Inline``
+ /// Only merge functions defined inside a class. Implies ``empty``.
+ /// \code
+ /// class Foo {
+ /// void f() { foo(); }
+ /// };
+ /// void f() {
+ /// foo();
+ /// }
+ /// void f() {}
+ /// \endcode
+ ///
+ /// * ``All``
+ /// Merge all functions fitting on a single line.
+ /// \code
+ /// class Foo {
+ /// void f() { foo(); }
+ /// };
+ /// void f() { bar(); }
+ /// \endcode
+ ///
+ /// Also can be specified as a nested configuration flag:
/// \code
- /// # Should be declared this way:
- /// AllowShortFunctionsOnASingleLine: Custom
- /// AllowShortFunctionsOnASingleLineOptions:
+ /// # Example of usage:
+ /// AllowShortFunctionsOnASingleLine: InlineOnly
+ ///
+ /// # or more granular control:
+ /// AllowShortFunctionsOnASingleLine:
/// Empty: false
/// Inline: true
/// All: false
/// \endcode
- struct ShortFunctionMergeFlags {
+ struct ShortFunctionStyle {
/// Merge top-level empty functions.
/// \code
/// void f() {}
@@ -912,7 +911,8 @@ struct FormatStyle {
/// }
/// \endcode
bool Inline;
- /// Merge all functions fitting on a single line.
+ /// Merge all functions fitting on a single line. Please note that this
+ /// control does not include Empty
/// \code
/// class Foo {
/// void f() { foo(); }
@@ -921,33 +921,19 @@ struct FormatStyle {
/// \endcode
bool Other;
- ShortFunctionMergeFlags() : Empty(false), Inline(false), Other(false) {}
-
- ShortFunctionMergeFlags(bool Empty, bool Inline, bool All)
- : Empty(Empty), Inline(Inline), Other(All) {}
-
- bool operator==(const ShortFunctionMergeFlags &R) const {
+ bool operator==(const ShortFunctionStyle &R) const {
return Empty == R.Empty && Inline == R.Inline && Other == R.Other;
}
- bool operator!=(const ShortFunctionMergeFlags &R) const {
- return !(*this == R);
- }
+ bool operator!=(const ShortFunctionStyle &R) const { return !(*this == R); }
+ ShortFunctionStyle() : Empty(false), Inline(false), Other(false) {}
+ ShortFunctionStyle(bool Empty, bool Inline, bool Other)
+ : Empty(Empty), Inline(Inline), Other(Other) {}
};
- /// Precise control over merging short functions
- ///
- /// If ``AllowShortFunctionsOnASingleLine`` is set to ``Custom``, use this to
- /// specify behavior in different situations.
- /// \code{.yaml}
- /// # Example of usage:
- /// AllowShortFunctionsOnASingleLine: Custom
- /// AllowShortFunctionsOnASingleLineOptions:
- /// Empty: false
- /// Inline: true
- /// All: false
- /// \endcode
- /// \version 21
- ShortFunctionMergeFlags AllowShortFunctionsOnASingleLineOptions;
+ /// Dependent on the value, ``int f() { return 0; }`` can be put on a
+ /// single line.
+ /// \version 3.5
+ ShortFunctionStyle AllowShortFunctionsOnASingleLine;
/// Different styles for handling short if statements.
enum ShortIfStyle : int8_t {
@@ -5352,8 +5338,6 @@ struct FormatStyle {
AllowShortEnumsOnASingleLine == R.AllowShortEnumsOnASingleLine &&
AllowShortFunctionsOnASingleLine ==
R.AllowShortFunctionsOnASingleLine &&
- AllowShortFunctionsOnASingleLineOptions ==
- R.AllowShortFunctionsOnASingleLineOptions &&
AllowShortIfStatementsOnASingleLine ==
R.AllowShortIfStatementsOnASingleLine &&
AllowShortLambdasOnASingleLine == R.AllowShortLambdasOnASingleLine &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index aff38f56f05e3..c1a7a0a034a22 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -613,21 +613,35 @@ template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> {
}
};
-template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
- 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);
- IO.enumCase(Value, "InlineOnly", FormatStyle::SFS_InlineOnly);
- IO.enumCase(Value, "Empty", FormatStyle::SFS_Empty);
- IO.enumCase(Value, "Custom", FormatStyle::SFS_Custom);
+template <> struct MappingTraits<FormatStyle::ShortFunctionStyle> {
+ static void enumInput(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
+ IO.enumCase(Value, "None", FormatStyle::ShortFunctionStyle({}));
+ IO.enumCase(Value, "Empty",
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false}));
+ IO.enumCase(Value, "Inline",
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false}));
+ IO.enumCase(Value, "InlineOnly",
+ FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+ /*Inline=*/true,
+ /*Other=*/false}));
+ IO.enumCase(Value, "All",
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true}));
+
+ // For backward compatibility.
+ IO.enumCase(Value, "true",
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true}));
+ IO.enumCase(Value, "false", FormatStyle::ShortFunctionStyle({}));
}
-};
-template <> struct MappingTraits<FormatStyle::ShortFunctionMergeFlags> {
- static void mapping(IO &IO, FormatStyle::ShortFunctionMergeFlags &Value) {
+ static void mapping(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
IO.mapOptional("Empty", Value.Empty);
IO.mapOptional("Inline", Value.Inline);
IO.mapOptional("Other", Value.Other);
@@ -991,8 +1005,6 @@ template <> struct MappingTraits<FormatStyle> {
Style.AllowShortEnumsOnASingleLine);
IO.mapOptional("AllowShortFunctionsOnASingleLine",
Style.AllowShortFunctionsOnASingleLine);
- IO.mapOptional("AllowShortFunctionsOnASingleLineOptions",
- Style.AllowShortFunctionsOnASingleLineOptions);
IO.mapOptional("AllowShortIfStatementsOnASingleLine",
Style.AllowShortIfStatementsOnASingleLine);
IO.mapOptional("AllowShortLambdasOnASingleLine",
@@ -1483,30 +1495,6 @@ static void expandPresetsSpacesInParens(FormatStyle &Expanded) {
Expanded.SpacesInParensOptions = {};
}
-static void expandPresetsShortFunctionsOnSingleLine(FormatStyle &Expanded) {
- if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Custom)
- return;
- // Reset all flags
- Expanded.AllowShortFunctionsOnASingleLineOptions = {};
-
- if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_None)
- return;
-
- if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty ||
- Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline) {
- Expanded.AllowShortFunctionsOnASingleLineOptions.Empty = true;
- }
-
- if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline ||
- Expanded.AllowShortFunctionsOnASingleLine ==
- FormatStyle::SFS_InlineOnly) {
- Expanded.AllowShortFunctionsOnASingleLineOptions.Inline = true;
- }
-
- if (Expanded.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All)
- Expanded.AllowShortFunctionsOnASingleLineOptions.Other = true;
-}
-
FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
FormatStyle LLVMStyle;
LLVMStyle.AccessModifierOffset = -2;
@@ -1535,9 +1523,10 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
LLVMStyle.AllowShortCompoundRequirementOnASingleLine = true;
LLVMStyle.AllowShortEnumsOnASingleLine = true;
- LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
- LLVMStyle.AllowShortFunctionsOnASingleLineOptions = {};
- LLVMStyle.AllowShortFunctionsOnASingleLineOptions.Other = true;
+ LLVMStyle.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
@@ -1824,9 +1813,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
GoogleStyle.AlignTrailingComments = {};
GoogleStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Never;
- GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
- GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
- GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+ GoogleStyle.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false});
GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
@@ -1836,9 +1826,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
} else if (Language == FormatStyle::LK_JavaScript) {
GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
- GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
- GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
- GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+ GoogleStyle.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false});
// TODO: still under discussion whether to switch to SLS_All.
GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
@@ -1855,9 +1846,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
GoogleStyle.SpacesInContainerLiterals = false;
} else if (Language == FormatStyle::LK_Proto) {
- GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
- GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
- GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+ GoogleStyle.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false});
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
// This affects protocol buffer options specifications and text protos.
// Text protos are currently mostly formatted inside C++ raw string literals
@@ -1876,9 +1868,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.IncludeStyle.IncludeBlocks =
tooling::IncludeStyle::IBS_Preserve;
} else if (Language == FormatStyle::LK_CSharp) {
- GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
- GoogleStyle.AllowShortFunctionsOnASingleLineOptions = {};
- GoogleStyle.AllowShortFunctionsOnASingleLineOptions.Empty = true;
+ GoogleStyle.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false});
GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
GoogleStyle.BreakStringLiterals = false;
GoogleStyle.ColumnLimit = 100;
@@ -1937,9 +1930,10 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
} else {
ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
- ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
- ChromiumStyle.AllowShortFunctionsOnASingleLineOptions = {};
- ChromiumStyle.AllowShortFunctionsOnASingleLineOptions.Inline = true;
+ ChromiumStyle.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false});
ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
ChromiumStyle.BinPackParameters = FormatStyle::BPPS_OnePerLine;
@@ -1953,9 +1947,10 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
FormatStyle getMozillaStyle() {
FormatStyle MozillaStyle = getLLVMStyle();
MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
- MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
- MozillaStyle.AllowShortFunctionsOnASingleLineOptions = {};
- MozillaStyle.AllowShortFunctionsOnASingleLineOptions.Inline = true;
+ MozillaStyle.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false});
MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
FormatStyle::DRTBS_TopLevel;
MozillaStyle.BinPackArguments = false;
@@ -2037,8 +2032,7 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
Style.BraceWrapping.BeforeWhile = false;
Style.PenaltyReturnTypeOnItsOwnLine = 1000;
Style.AllowShortEnumsOnASingleLine = false;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
- Style.AllowShortFunctionsOnASingleLineOptions = {};
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
Style.AllowShortCaseLabelsOnASingleLine = false;
Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
Style.AllowShortLoopsOnASingleLine = false;
@@ -2210,7 +2204,6 @@ std::string configurationAsText(const FormatStyle &Style) {
expandPresetsBraceWrapping(NonConstStyle);
expandPresetsSpaceBeforeParens(NonConstStyle);
expandPresetsSpacesInParens(NonConstStyle);
- expandPresetsShortFunctionsOnSingleLine(NonConstStyle);
Output << NonConstStyle;
return Stream.str();
@@ -3773,7 +3766,6 @@ reformat(const FormatStyle &Style, StringRef Code,
expandPresetsBraceWrapping(Expanded);
expandPresetsSpaceBeforeParens(Expanded);
expandPresetsSpacesInParens(Expanded);
- expandPresetsShortFunctionsOnSingleLine(Expanded);
Expanded.InsertBraces = false;
Expanded.RemoveBracesLLVM = false;
Expanded.RemoveParentheses = FormatStyle::RPS_Leave;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index cdf46f65e8b52..db2f8766f8d40 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5687,10 +5687,11 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
!Left.Children.empty()) {
// Support AllowShortFunctionsOnASingleLine for JavaScript.
- return (!Style.AllowShortFunctionsOnASingleLineOptions.Inline &&
- !Style.AllowShortFunctionsOnASingleLineOptions.Other) ||
+ return (!Style.AllowShortFunctionsOnASingleLine.Inline &&
+ !Style.AllowShortFunctionsOnASingleLine.Other) ||
(Left.NestingLevel == 0 && Line.Level == 0 &&
- Style.AllowShortFunctionsOnASingleLineOptions.Inline);
+ Style.AllowShortFunctionsOnASingleLine.Inline &&
+ !Style.AllowShortFunctionsOnASingleLine.Other);
}
} else if (Style.Language == FormatStyle::LK_Java) {
if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 6f30bbc8a9e5f..fdec849cf363a 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -293,14 +293,14 @@ class LineJoiner {
auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine,
TheLine]() {
- if (Style.AllowShortFunctionsOnASingleLineOptions.Other)
+ if (Style.AllowShortFunctionsOnASingleLine.Other)
return true;
- if (Style.AllowShortFunctionsOnASingleLineOptions.Empty &&
+ if (Style.AllowShortFunctionsOnASingleLine.Empty &&
NextLine.First->is(tok::r_brace)) {
return true;
}
- if (Style.AllowShortFunctionsOnASingleLineOptions.Inline) {
+ if (Style.AllowShortFunctionsOnASingleLine.Inline) {
// Just checking TheLine->Level != 0 is not enough, because it
// provokes treating functions inside indented namespaces as short.
if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
@@ -550,7 +550,7 @@ class LineJoiner {
unsigned MergedLines = 0;
if (MergeShortFunctions ||
- (Style.AllowShortFunctionsOnASingleLineOptions.Empty &&
+ (Style.AllowShortFunctionsOnASingleLine.Empty &&
NextLine.First == NextLine.Last && I + 2 != E &&
I[2]->First->is(tok::r_brace))) {
MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 16ab406c9cade..c022db94cdb6a 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -256,9 +256,6 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
- CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Empty);
- CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Inline);
- CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLineOptions, Other);
}
#undef CHECK_PARSE_BOOL
@@ -614,23 +611,40 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE("AllowShortBlocksOnASingleLine: true",
AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ // Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
- AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None);
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle({}));
CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
- AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Inline);
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false}));
CHECK_PARSE("AllowShortFunctionsOnASingleLine: Empty",
- AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Empty);
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false}));
CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
- AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
- CHECK_PARSE("AllowShortFunctionsOnASingleLine: Custom",
- AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Custom);
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true}));
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: InlineOnly",
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+ /*Inline=*/true,
+ /*Other=*/false}));
// For backward compatibility:
CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
- AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None);
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle({}));
CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
- AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true}));
Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
CHECK_PARSE("AllowShortLambdasOnASingleLine: None",
diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
index b26b9f4f4ff62..d3d0a0b56b5a0 100644
--- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
+++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
@@ -540,7 +540,7 @@ TEST_F(DefinitionBlockSeparatorTest, Leave) {
TEST_F(DefinitionBlockSeparatorTest, CSharp) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
Style.AllowShortEnumsOnASingleLine = false;
verifyFormat("namespace {\r\n"
"public class SomeTinyClass {\r\n"
@@ -581,7 +581,7 @@ TEST_F(DefinitionBlockSeparatorTest, CSharp) {
TEST_F(DefinitionBlockSeparatorTest, JavaScript) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_JavaScript);
Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
Style.AllowShortEnumsOnASingleLine = false;
verifyFormat("export const enum Foo {\n"
" A = 1,\n"
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 79ee1230eb6a7..382e9e855b622 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -388,7 +388,10 @@ TEST_F(FormatTest, RemovesEmptyLines) {
"} // namespace");
FormatStyle Style = getLLVMStyle();
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
Style.MaxEmptyLinesToKeep = 2;
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
Style.BraceWrapping.AfterClass = true;
@@ -3377,13 +3380,16 @@ TEST_F(FormatTest, MultiLineControlStatements) {
Style.BraceWrapping.AfterFunction = true;
Style.BraceWrapping.AfterStruct = false;
Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
Style.ColumnLimit = 80;
verifyFormat("void shortfunction() { bar(); }", Style);
verifyFormat("struct T shortfunction() { return bar(); }", Style);
verifyFormat("struct T {};", Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
verifyFormat("void shortfunction()\n"
"{\n"
" bar();\n"
@@ -3398,7 +3404,10 @@ TEST_F(FormatTest, MultiLineControlStatements) {
Style.BraceWrapping.AfterFunction = false;
Style.BraceWrapping.AfterStruct = true;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
verifyFormat("void shortfunction() { bar(); }", Style);
verifyFormat("struct T shortfunction() { return bar(); }", Style);
verifyFormat("struct T\n"
@@ -3406,7 +3415,7 @@ TEST_F(FormatTest, MultiLineControlStatements) {
"};",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
verifyFormat("void shortfunction() {\n"
" bar();\n"
"}",
@@ -4201,7 +4210,9 @@ TEST_F(FormatTest, FormatsNamespaces) {
FormatStyle ShortInlineFunctions = getLLVMStyle();
ShortInlineFunctions.NamespaceIndentation = FormatStyle::NI_All;
ShortInlineFunctions.AllowShortFunctionsOnASingleLine =
- FormatStyle::SFS_Inline;
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false});
verifyFormat("namespace {\n"
" void f() {\n"
" return;\n"
@@ -8326,7 +8337,7 @@ TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
"};",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
verifyNoChange("SomeClass::Constructor() :\n"
" a(a), b(b), c(c) {\n"
"}",
@@ -8337,7 +8348,10 @@ TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
Style);
Style.ColumnLimit = 80;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
Style.ConstructorInitializerIndentWidth = 2;
verifyFormat("SomeClass::Constructor() : a(a), b(b), c(c) {}", Style);
verifyFormat("SomeClass::Constructor() :\n"
@@ -12671,7 +12685,8 @@ TEST_F(FormatTest, UnderstandsAttributes) {
verifyFormat("__attr1(nodebug) ::qualified_type f();", CustomAttrs);
// Check that these are not parsed as function declarations:
- CustomAttrs.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ CustomAttrs.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({});
CustomAttrs.BreakBeforeBraces = FormatStyle::BS_Allman;
verifyFormat("SomeType s(InitValue);", CustomAttrs);
verifyFormat("SomeType s{InitValue};", CustomAttrs);
@@ -12772,7 +12787,8 @@ TEST_F(FormatTest, UnderstandsSquareAttributes) {
// Make sure we do not parse attributes as lambda introducers.
FormatStyle MultiLineFunctions = getLLVMStyle();
- MultiLineFunctions.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ MultiLineFunctions.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({});
verifyFormat("[[unused]] int b() {\n"
" return 42;\n"
"}",
@@ -14870,7 +14886,8 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) {
TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
FormatStyle DoNotMerge = getLLVMStyle();
- DoNotMerge.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ DoNotMerge.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({});
verifyFormat("void f() { return 42; }");
verifyFormat("void f() {\n"
@@ -14941,7 +14958,7 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
FormatStyle DoNotMergeNoColumnLimit = NoColumnLimit;
DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine =
- FormatStyle::SFS_None;
+ FormatStyle::ShortFunctionStyle({});
verifyFormat("A() : b(0) {\n"
"}",
DoNotMergeNoColumnLimit);
@@ -14989,7 +15006,10 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) {
FormatStyle MergeEmptyOnly = getLLVMStyle();
- MergeEmptyOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ MergeEmptyOnly.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false});
verifyFormat("class C {\n"
" int f() {}\n"
"};",
@@ -15018,7 +15038,10 @@ TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) {
TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
FormatStyle MergeInlineOnly = getLLVMStyle();
- MergeInlineOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ MergeInlineOnly.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false});
verifyFormat("class C {\n"
" int f() { return 42; }\n"
"};",
@@ -15122,10 +15145,10 @@ TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
TEST_F(FormatTest, CustomShortFunctionOptions) {
FormatStyle CustomEmpty = getLLVMStyle();
- CustomEmpty.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
- CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Empty = true;
- CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Inline = false;
- CustomEmpty.AllowShortFunctionsOnASingleLineOptions.Other = false;
+ CustomEmpty.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false});
// Empty functions should be on a single line
verifyFormat("int f() {}", CustomEmpty);
@@ -15161,10 +15184,10 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
// Test with Inline = true, All = false
FormatStyle CustomInline = getLLVMStyle();
- CustomInline.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
- CustomInline.AllowShortFunctionsOnASingleLineOptions.Empty = false;
- CustomInline.AllowShortFunctionsOnASingleLineOptions.Inline = true;
- CustomInline.AllowShortFunctionsOnASingleLineOptions.Other = false;
+ CustomInline.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+ /*Inline=*/true,
+ /*Other=*/false});
verifyFormat("class C {\n"
" int f() {}\n"
@@ -15188,10 +15211,10 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
// Test with All = true
FormatStyle CustomAll = getLLVMStyle();
- CustomAll.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
- CustomAll.AllowShortFunctionsOnASingleLineOptions.Empty = false;
- CustomAll.AllowShortFunctionsOnASingleLineOptions.Inline = false;
- CustomAll.AllowShortFunctionsOnASingleLineOptions.Other = true;
+ CustomAll.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
// All functions should be on a single line if they fit
verifyFormat("int f() { return 42; }", CustomAll);
@@ -15209,10 +15232,10 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
// Test various combinations
FormatStyle CustomMixed = getLLVMStyle();
- CustomMixed.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Custom;
- CustomMixed.AllowShortFunctionsOnASingleLineOptions.Empty = true;
- CustomMixed.AllowShortFunctionsOnASingleLineOptions.Inline = true;
- CustomMixed.AllowShortFunctionsOnASingleLineOptions.Other = false;
+ CustomMixed.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false});
// Empty functions should be on a single line
verifyFormat("int f() {}", CustomMixed);
@@ -15237,7 +15260,9 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
FormatStyle MergeInlineOnly = getLLVMStyle();
MergeInlineOnly.AllowShortFunctionsOnASingleLine =
- FormatStyle::SFS_InlineOnly;
+ FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+ /*Inline=*/true,
+ /*Other=*/false});
verifyFormat("class C {\n"
" int f() { return 42; }\n"
"};",
@@ -15282,7 +15307,7 @@ TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
TEST_F(FormatTest, SplitEmptyFunction) {
FormatStyle Style = getLLVMStyleWithColumns(40);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
Style.BraceWrapping.AfterFunction = true;
Style.BraceWrapping.SplitEmptyFunction = false;
@@ -15301,7 +15326,10 @@ TEST_F(FormatTest, SplitEmptyFunction) {
"}",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false});
verifyFormat("int f() {}", Style);
verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
"{}",
@@ -15312,7 +15340,10 @@ TEST_F(FormatTest, SplitEmptyFunction) {
"}",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false});
verifyFormat("class Foo {\n"
" int f() {}\n"
"};",
@@ -15334,7 +15365,10 @@ TEST_F(FormatTest, SplitEmptyFunction) {
"};",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
verifyFormat("int f() {}", Style);
verifyFormat("int f() { return 0; }", Style);
verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
@@ -15349,7 +15383,7 @@ TEST_F(FormatTest, SplitEmptyFunction) {
TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
FormatStyle Style = getLLVMStyleWithColumns(40);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
Style.BraceWrapping.AfterFunction = true;
Style.BraceWrapping.SplitEmptyFunction = true;
@@ -15379,7 +15413,10 @@ TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
TEST_F(FormatTest, KeepShortFunctionAfterPPElse) {
FormatStyle Style = getLLVMStyle();
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
verifyFormat("#ifdef A\n"
"int f() {}\n"
"#else\n"
@@ -21492,7 +21529,9 @@ TEST_F(FormatTest, WhitesmithsBraceBreaking) {
// Make a few changes to the style for testing purposes
WhitesmithsBraceStyle.AllowShortFunctionsOnASingleLine =
- FormatStyle::SFS_Empty;
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false});
WhitesmithsBraceStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None;
// FIXME: this test case can't decide whether there should be a blank line
@@ -23038,7 +23077,7 @@ TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
"}",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
verifyFormat("SomeClass::Constructor()\n"
" : a(a)\n"
" , b(b)\n"
@@ -23049,7 +23088,10 @@ TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
Style);
Style.ColumnLimit = 80;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
Style.ConstructorInitializerIndentWidth = 2;
verifyFormat("SomeClass::Constructor()\n"
" : a(a)\n"
@@ -27198,7 +27240,7 @@ TEST_F(FormatTest, FormatDecayCopy) {
TEST_F(FormatTest, Cpp20ModulesSupport) {
FormatStyle Style = getLLVMStyle();
Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
verifyFormat("export import foo;", Style);
verifyFormat("export import foo:bar;", Style);
diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp
index 151f7072e0c65..22c757509f5fb 100644
--- a/clang/unittests/Format/FormatTestCSharp.cpp
+++ b/clang/unittests/Format/FormatTestCSharp.cpp
@@ -1660,7 +1660,10 @@ TEST_F(FormatTestCSharp, EmptyShortBlock) {
TEST_F(FormatTestCSharp, ShortFunctions) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
Style.NamespaceIndentation = FormatStyle::NI_All;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false});
verifyFormat("interface Interface {\n"
" void f() { return; }\n"
"};",
diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp
index 78c9f887a159b..2108bb21f192e 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -1010,7 +1010,10 @@ TEST_F(FormatTestJS, TrailingCommaInsertion) {
TEST_F(FormatTestJS, FunctionLiterals) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false});
verifyFormat("doFoo(function() {});");
verifyFormat("doFoo(function() { return 1; });", Style);
verifyFormat("var func = function() {\n"
@@ -1123,7 +1126,10 @@ TEST_F(FormatTestJS, DontWrapEmptyLiterals) {
TEST_F(FormatTestJS, InliningFunctionLiterals) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false});
verifyFormat("var func = function() {\n"
" return 1;\n"
"};",
@@ -1138,7 +1144,10 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
"}",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
verifyFormat("var func = function() { return 1; };", Style);
verifyFormat("var func = doSomething(function() { return 1; });", Style);
verifyFormat(
@@ -1149,7 +1158,7 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
"}",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
verifyFormat("var func = function() {\n"
" return 1;\n"
"};",
@@ -1171,7 +1180,10 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
"}",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false});
verifyFormat("var func = function() {\n"
" return 1;\n"
"};",
@@ -1180,7 +1192,10 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
TEST_F(FormatTestJS, MultipleFunctionLiterals) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/true});
verifyFormat("promise.then(\n"
" function success() {\n"
" doFoo();\n"
diff --git a/clang/unittests/Format/FormatTestJava.cpp b/clang/unittests/Format/FormatTestJava.cpp
index 33998bc7ff858..bba6541395171 100644
--- a/clang/unittests/Format/FormatTestJava.cpp
+++ b/clang/unittests/Format/FormatTestJava.cpp
@@ -594,7 +594,10 @@ TEST_F(FormatTestJava, RetainsLogicalShifts) {
TEST_F(FormatTestJava, ShortFunctions) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_Java);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/true,
+ /*Inline=*/true,
+ /*Other=*/false});
verifyFormat("enum Enum {\n"
" E1,\n"
" E2;\n"
>From 7f80e4adcac43f3b2c393a499627a1ca4d0beaef Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Tue, 8 Apr 2025 21:13:35 -0700
Subject: [PATCH 04/17] fixed documentation error
---
clang/docs/ClangFormatStyleOptions.rst | 1 +
clang/include/clang/Format/Format.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 6f3b9f798093f..1c55b74395062 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1911,6 +1911,7 @@ the configuration (without a prefix: ``Auto``).
statement.
They can be read as a whole for compatibility. The choices are:
+
* ``None``
Never merge functions into a single line.
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 2278bf3966296..e5c031c7b249f 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -829,6 +829,7 @@ struct FormatStyle {
/// statement.
///
/// They can be read as a whole for compatibility. The choices are:
+ ///
/// * ``None``
/// Never merge functions into a single line.
///
>From bbe22735987f4f24d278e73df74e59ad9b246d95 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Wed, 9 Apr 2025 19:27:10 -0700
Subject: [PATCH 05/17] Fixed PR comments
---
clang/docs/ClangFormatStyleOptions.rst | 2 +-
clang/include/clang/Format/Format.h | 2 +-
clang/lib/Format/TokenAnnotator.cpp | 8 +++-----
clang/unittests/Format/ConfigParseTest.cpp | 1 -
4 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 1c55b74395062..d67c8891a4506 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1975,7 +1975,7 @@ the configuration (without a prefix: ``Auto``).
AllowShortFunctionsOnASingleLine:
Empty: false
Inline: true
- All: false
+ Other: false
* ``bool Empty`` Merge top-level empty functions.
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index e5c031c7b249f..7836fa91b20a8 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -887,7 +887,7 @@ struct FormatStyle {
/// AllowShortFunctionsOnASingleLine:
/// Empty: false
/// Inline: true
- /// All: false
+ /// Other: false
/// \endcode
struct ShortFunctionStyle {
/// Merge top-level empty functions.
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index db2f8766f8d40..f85ddbe2f0523 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5687,11 +5687,9 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
!Left.Children.empty()) {
// Support AllowShortFunctionsOnASingleLine for JavaScript.
- return (!Style.AllowShortFunctionsOnASingleLine.Inline &&
- !Style.AllowShortFunctionsOnASingleLine.Other) ||
- (Left.NestingLevel == 0 && Line.Level == 0 &&
- Style.AllowShortFunctionsOnASingleLine.Inline &&
- !Style.AllowShortFunctionsOnASingleLine.Other);
+ return !(Left.NestingLevel == 0 && Line.Level == 0
+ ? Style.AllowShortFunctionsOnASingleLine.Other
+ : Style.AllowShortFunctionsOnASingleLine.Inline);
}
} else if (Style.Language == FormatStyle::LK_Java) {
if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index c022db94cdb6a..b48dd0a737eea 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -611,7 +611,6 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE("AllowShortBlocksOnASingleLine: true",
AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
- // Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
AllowShortFunctionsOnASingleLine,
FormatStyle::ShortFunctionStyle({}));
>From 5ff5810b53308fb2df457b339743991b1fcc9695 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Sun, 13 Apr 2025 15:14:16 -0700
Subject: [PATCH 06/17] marked options as deprecated
---
clang/docs/ClangFormatStyleOptions.rst | 11 ++++++++---
clang/include/clang/Format/Format.h | 11 ++++++++---
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index d67c8891a4506..a01b9baf482e3 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1918,7 +1918,8 @@ the configuration (without a prefix: ``Auto``).
* ``InlineOnly``
Only merge functions defined inside a class. Same as ``inline``,
except it does not implies ``empty``: i.e. top level empty functions
- are not merged either.
+ are not merged either. This option is **deprecated** and is retained
+ for backwards compatibility. See ``Inline`` of ``ShortFunctionStyle``.
.. code-block:: c++
@@ -1932,7 +1933,9 @@ the configuration (without a prefix: ``Auto``).
}
* ``Empty``
- Only merge empty functions.
+ Only merge empty functions. This option is **deprecated** and is
+ retained for backwards compatibility. See ``Empty`` of
+ ``ShortFunctionStyle``.
.. code-block:: c++
@@ -1942,7 +1945,9 @@ the configuration (without a prefix: ``Auto``).
}
* ``Inline``
- Only merge functions defined inside a class. Implies ``empty``.
+ Only merge functions defined inside a class. Implies ``empty``. This
+ option is **deprecated** and is retained for backwards compatibility.
+ See ``Inline`` and ``Empty`` of ``ShortFunctionStyle``.
.. code-block:: c++
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 7836fa91b20a8..448e8d0f2eb77 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -836,7 +836,8 @@ struct FormatStyle {
/// * ``InlineOnly``
/// Only merge functions defined inside a class. Same as ``inline``,
/// except it does not implies ``empty``: i.e. top level empty functions
- /// are not merged either.
+ /// are not merged either. This option is **deprecated** and is retained
+ /// for backwards compatibility. See ``Inline`` of ``ShortFunctionStyle``.
/// \code
/// class Foo {
/// void f() { foo(); }
@@ -849,7 +850,9 @@ struct FormatStyle {
/// \endcode
///
/// * ``Empty``
- /// Only merge empty functions.
+ /// Only merge empty functions. This option is **deprecated** and is
+ /// retained for backwards compatibility. See ``Empty`` of
+ /// ``ShortFunctionStyle``.
/// \code
/// void f() {}
/// void f2() {
@@ -858,7 +861,9 @@ struct FormatStyle {
/// \endcode
///
/// * ``Inline``
- /// Only merge functions defined inside a class. Implies ``empty``.
+ /// Only merge functions defined inside a class. Implies ``empty``. This
+ /// option is **deprecated** and is retained for backwards compatibility.
+ /// See ``Inline`` and ``Empty`` of ``ShortFunctionStyle``.
/// \code
/// class Foo {
/// void f() { foo(); }
>From 70eafeabdff7f1f3e765f7dae29eec9c202170c8 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Tue, 15 Apr 2025 20:38:36 -0700
Subject: [PATCH 07/17] fixed PR comments
---
clang/include/clang/Format/Format.h | 3 +++
clang/lib/Format/TokenAnnotator.cpp | 2 +-
clang/lib/Format/UnwrappedLineFormatter.cpp | 5 +++--
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 448e8d0f2eb77..b56806ca2ccfa 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -934,6 +934,9 @@ struct FormatStyle {
ShortFunctionStyle() : Empty(false), Inline(false), Other(false) {}
ShortFunctionStyle(bool Empty, bool Inline, bool Other)
: Empty(Empty), Inline(Inline), Other(Other) {}
+ bool isAll() const {
+ return Empty && Inline && Other;
+ }
};
/// Dependent on the value, ``int f() { return 0; }`` can be put on a
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index f85ddbe2f0523..73ff1c537d1e8 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5688,7 +5688,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
!Left.Children.empty()) {
// Support AllowShortFunctionsOnASingleLine for JavaScript.
return !(Left.NestingLevel == 0 && Line.Level == 0
- ? Style.AllowShortFunctionsOnASingleLine.Other
+ ? Style.AllowShortFunctionsOnASingleLine.isAll()
: Style.AllowShortFunctionsOnASingleLine.Inline);
}
} else if (Style.Language == FormatStyle::LK_Java) {
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index fdec849cf363a..c6b9ad02a22b5 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -293,14 +293,15 @@ class LineJoiner {
auto ShouldMergeShortFunctions = [this, &I, &NextLine, PreviousLine,
TheLine]() {
- if (Style.AllowShortFunctionsOnASingleLine.Other)
+ if (Style.AllowShortFunctionsOnASingleLine.isAll())
return true;
if (Style.AllowShortFunctionsOnASingleLine.Empty &&
NextLine.First->is(tok::r_brace)) {
return true;
}
- if (Style.AllowShortFunctionsOnASingleLine.Inline) {
+ if (Style.AllowShortFunctionsOnASingleLine.Inline &&
+ !Style.AllowShortFunctionsOnASingleLine.isAll()) {
// Just checking TheLine->Level != 0 is not enough, because it
// provokes treating functions inside indented namespaces as short.
if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
>From dd6493d703237cc0a1c9a8e61696482cd91edb92 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Tue, 15 Apr 2025 21:42:01 -0700
Subject: [PATCH 08/17] added usage of 'other'
---
clang/include/clang/Format/Format.h | 4 +-
clang/lib/Format/UnwrappedLineFormatter.cpp | 63 +++++++++++----------
clang/unittests/Format/FormatTest.cpp | 20 +++++++
3 files changed, 55 insertions(+), 32 deletions(-)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index b56806ca2ccfa..38b68651e0322 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -934,9 +934,7 @@ struct FormatStyle {
ShortFunctionStyle() : Empty(false), Inline(false), Other(false) {}
ShortFunctionStyle(bool Empty, bool Inline, bool Other)
: Empty(Empty), Inline(Inline), Other(Other) {}
- bool isAll() const {
- return Empty && Inline && Other;
- }
+ bool isAll() const { return Empty && Inline && Other; }
};
/// Dependent on the value, ``int f() { return 0; }`` can be put on a
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index c6b9ad02a22b5..71d53c1c60c58 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -295,47 +295,52 @@ class LineJoiner {
TheLine]() {
if (Style.AllowShortFunctionsOnASingleLine.isAll())
return true;
- if (Style.AllowShortFunctionsOnASingleLine.Empty &&
- NextLine.First->is(tok::r_brace)) {
+
+ // there might be a case where empty function is in class, so need to
+ // check inline later
+ bool empty_function = NextLine.First->is(tok::r_brace);
+ if (Style.AllowShortFunctionsOnASingleLine.Empty && empty_function)
return true;
- }
- if (Style.AllowShortFunctionsOnASingleLine.Inline &&
- !Style.AllowShortFunctionsOnASingleLine.isAll()) {
+ if (TheLine->Level != 0) {
+ if (!Style.AllowShortFunctionsOnASingleLine.Inline)
+ return false;
+
// Just checking TheLine->Level != 0 is not enough, because it
// provokes treating functions inside indented namespaces as short.
if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
return true;
- if (TheLine->Level != 0) {
- if (!PreviousLine)
- return false;
-
- // TODO: Use IndentTracker to avoid loop?
- // Find the last line with lower level.
- const AnnotatedLine *Line = nullptr;
- for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) {
- assert(*J);
- if (!(*J)->InPPDirective && !(*J)->isComment() &&
- (*J)->Level < TheLine->Level) {
- Line = *J;
- break;
- }
+ if (!PreviousLine)
+ return false;
+
+ // TODO: Use IndentTracker to avoid loop?
+ // Find the last line with lower level.
+ const AnnotatedLine *Line = nullptr;
+ for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) {
+ assert(*J);
+ if (!(*J)->InPPDirective && !(*J)->isComment() &&
+ (*J)->Level < TheLine->Level) {
+ Line = *J;
+ break;
}
+ }
- if (!Line)
- return false;
+ if (!Line)
+ return false;
- // Check if the found line starts a record.
- const auto *LastNonComment = Line->getLastNonComment();
- // There must be another token (usually `{`), because we chose a
- // non-PPDirective and non-comment line that has a smaller level.
- assert(LastNonComment);
- return isRecordLBrace(*LastNonComment);
- }
+ // Check if the found line starts a record.
+ const auto *LastNonComment = Line->getLastNonComment();
+ // There must be another token (usually `{`), because we chose a
+ // non-PPDirective and non-comment line that has a smaller level.
+ assert(LastNonComment);
+ return isRecordLBrace(*LastNonComment);
}
- return false;
+ if (empty_function && !Style.AllowShortFunctionsOnASingleLine.Empty)
+ return false;
+
+ return Style.AllowShortFunctionsOnASingleLine.Other;
};
bool MergeShortFunctions = ShouldMergeShortFunctions();
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 382e9e855b622..b780dee7660ae 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15255,6 +15255,26 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
" return 42;\n"
"}",
CustomMixed);
+
+ FormatStyle OnlyOther = getLLVMStyle();
+ OnlyOther.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+ /*Inline=*/false,
+ /*Other=*/true});
+ verifyFormat("void topLevelEmpty() {\n"
+ "}",
+ OnlyOther);
+
+ verifyFormat("void topLevelNonEmpty() { return; }", OnlyOther);
+
+ verifyFormat("class C {\n"
+ " int inlineEmpty() {\n"
+ " }\n"
+ " int inlineNonempty() {\n"
+ " return 42;\n"
+ " }\n"
+ "};",
+ OnlyOther);
}
TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
>From 3c0fa142bec76b01557d5d1b0b1d235541cf2985 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Sun, 20 Apr 2025 21:08:28 -0700
Subject: [PATCH 09/17] fixed ShortFunctionStyle.Other case for JS
---
clang/lib/Format/TokenAnnotator.cpp | 24 ++++++++++++++++---
clang/unittests/Format/FormatTestJS.cpp | 31 +++++++++++++++++++++++++
2 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 9ef060f83bc0b..02b5140e763cf 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5685,9 +5685,27 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
!Left.Children.empty()) {
// Support AllowShortFunctionsOnASingleLine for JavaScript.
- return !(Left.NestingLevel == 0 && Line.Level == 0
- ? Style.AllowShortFunctionsOnASingleLine.isAll()
- : Style.AllowShortFunctionsOnASingleLine.Inline);
+ const auto &shortFuncConfig = Style.AllowShortFunctionsOnASingleLine;
+
+ // SFS_All
+ if (shortFuncConfig.isAll())
+ return false;
+
+ // SFS_None and SFS_Empty
+ if (shortFuncConfig == FormatStyle::ShortFunctionStyle{})
+ return true;
+
+ // SFS_Empty
+ if (shortFuncConfig == FormatStyle::ShortFunctionStyle{/*Empty=*/true,
+ /*Inline=*/false,
+ /*Other=*/false}) {
+ return true;
+ }
+
+ if (Left.NestingLevel == 0 && Line.Level == 0)
+ return shortFuncConfig.Inline && !shortFuncConfig.Other;
+
+ return shortFuncConfig.Other;
}
} else if (Style.isJava()) {
if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp
index cc091df1f04dc..03e55e4498fd4 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -1195,6 +1195,37 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
Style);
}
+TEST_F(FormatTestJS, InliningFunctionLiteralsNew) {
+ FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
+ Style.AllowShortFunctionsOnASingleLine =
+ FormatStyle::ShortFunctionStyle({/*Empty=*/false,
+ /*Inline=*/false,
+ /*Other=*/true});
+ verifyFormat("var func = function() { return 1; };", Style);
+ verifyFormat("var func = doSomething(function() {\n"
+ " return 1;\n"
+ "});",
+ Style);
+ verifyFormat("var outer = function() {\n"
+ " var inner = function() {\n"
+ " return 1;\n"
+ " }\n"
+ "};",
+ Style);
+ verifyFormat("function outer1(a, b) {\n"
+ " function inner1(a, b) {\n"
+ " return a;\n"
+ " }\n"
+ "}",
+ Style);
+
+ verifyFormat("function outer1(a, b) {\n"
+ " function inner1_empty(a, b) {\n"
+ " }\n"
+ "}",
+ Style);
+}
+
TEST_F(FormatTestJS, MultipleFunctionLiterals) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
Style.AllowShortFunctionsOnASingleLine =
>From 7825f535be13082c93dc67459b37e6288266e450 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Mon, 12 May 2025 21:01:06 -0700
Subject: [PATCH 10/17] fixed first comment - simplified code
---
clang/lib/Format/TokenAnnotator.cpp | 23 +++--------------------
1 file changed, 3 insertions(+), 20 deletions(-)
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 02b5140e763cf..4ee887f482606 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5685,27 +5685,10 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
if (Right.is(tok::r_brace) && Left.is(tok::l_brace) &&
!Left.Children.empty()) {
// Support AllowShortFunctionsOnASingleLine for JavaScript.
- const auto &shortFuncConfig = Style.AllowShortFunctionsOnASingleLine;
-
- // SFS_All
- if (shortFuncConfig.isAll())
- return false;
-
- // SFS_None and SFS_Empty
- if (shortFuncConfig == FormatStyle::ShortFunctionStyle{})
- return true;
-
- // SFS_Empty
- if (shortFuncConfig == FormatStyle::ShortFunctionStyle{/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false}) {
- return true;
- }
-
if (Left.NestingLevel == 0 && Line.Level == 0)
- return shortFuncConfig.Inline && !shortFuncConfig.Other;
-
- return shortFuncConfig.Other;
+ return !Style.AllowShortFunctionsOnASingleLine.Other;
+
+ return !Style.AllowShortFunctionsOnASingleLine.Inline;
}
} else if (Style.isJava()) {
if (Right.is(tok::plus) && Left.is(tok::string_literal) && AfterRight &&
>From 9dbd674f61971a8faed32363effecfb82db12734 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Mon, 12 May 2025 21:07:54 -0700
Subject: [PATCH 11/17] removed code related to Only Other option
---
.gitignore | 1 +
clang/lib/Format/TokenAnnotator.cpp | 2 +-
clang/lib/Format/UnwrappedLineFormatter.cpp | 71 ++++++++++-----------
clang/unittests/Format/FormatTest.cpp | 20 ------
4 files changed, 35 insertions(+), 59 deletions(-)
diff --git a/.gitignore b/.gitignore
index a84268a7f6863..2b4aa551d06c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,3 +73,4 @@ pythonenv*
/clang/utils/analyzer/projects/*/RefScanBuildResults
# automodapi puts generated documentation files here.
/lldb/docs/python_api/
+clang-build/
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 4ee887f482606..1455c21fa7d7f 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5687,7 +5687,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// Support AllowShortFunctionsOnASingleLine for JavaScript.
if (Left.NestingLevel == 0 && Line.Level == 0)
return !Style.AllowShortFunctionsOnASingleLine.Other;
-
+
return !Style.AllowShortFunctionsOnASingleLine.Inline;
}
} else if (Style.isJava()) {
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 5866d33572116..8e344c820e119 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -294,56 +294,51 @@ class LineJoiner {
if (Style.AllowShortFunctionsOnASingleLine.isAll())
return true;
- // there might be a case where empty function is in class, so need to
- // check inline later
- bool empty_function = NextLine.First->is(tok::r_brace);
- if (Style.AllowShortFunctionsOnASingleLine.Empty && empty_function)
+ if (Style.AllowShortFunctionsOnASingleLine.Empty &&
+ NextLine.First->is(tok::r_brace)) {
return true;
+ }
- if (TheLine->Level != 0) {
- if (!Style.AllowShortFunctionsOnASingleLine.Inline)
- return false;
-
+ if (Style.AllowShortFunctionsOnASingleLine.Inline) {
// Just checking TheLine->Level != 0 is not enough, because it
// provokes treating functions inside indented namespaces as short.
if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
return true;
- if (!PreviousLine)
- return false;
-
- // TODO: Use IndentTracker to avoid loop?
- // Find the last line with lower level.
- const AnnotatedLine *Line = nullptr;
- for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) {
- assert(*J);
- if ((*J)->InPPDirective || (*J)->isComment() ||
- (*J)->Level > TheLine->Level) {
- continue;
- }
- if ((*J)->Level < TheLine->Level ||
- (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
- (*J)->First->is(tok::l_brace))) {
- Line = *J;
- break;
+ if (TheLine->Level != 0) {
+ if (!PreviousLine)
+ return false;
+
+ // TODO: Use IndentTracker to avoid loop?
+ // Find the last line with lower level.
+ const AnnotatedLine *Line = nullptr;
+ for (auto J = I - 1; J >= AnnotatedLines.begin(); --J) {
+ assert(*J);
+ if ((*J)->InPPDirective || (*J)->isComment() ||
+ (*J)->Level > TheLine->Level) {
+ continue;
+ }
+ if ((*J)->Level < TheLine->Level ||
+ (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths &&
+ (*J)->First->is(tok::l_brace))) {
+ Line = *J;
+ break;
+ }
}
- }
- if (!Line)
- return false;
+ if (!Line)
+ return false;
- // Check if the found line starts a record.
- const auto *LastNonComment = Line->getLastNonComment();
- // There must be another token (usually `{`), because we chose a
- // non-PPDirective and non-comment line that has a smaller level.
- assert(LastNonComment);
- return isRecordLBrace(*LastNonComment);
+ // Check if the found line starts a record.
+ const auto *LastNonComment = Line->getLastNonComment();
+ // There must be another token (usually `{`), because we chose a
+ // non-PPDirective and non-comment line that has a smaller level.
+ assert(LastNonComment);
+ return isRecordLBrace(*LastNonComment);
+ }
}
- if (empty_function && !Style.AllowShortFunctionsOnASingleLine.Empty)
- return false;
-
- return Style.AllowShortFunctionsOnASingleLine.Other;
+ return false;
};
bool MergeShortFunctions = ShouldMergeShortFunctions();
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index c84c0510cce0f..ed1582d3417c4 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15255,26 +15255,6 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
" return 42;\n"
"}",
CustomMixed);
-
- FormatStyle OnlyOther = getLLVMStyle();
- OnlyOther.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/false,
- /*Inline=*/false,
- /*Other=*/true});
- verifyFormat("void topLevelEmpty() {\n"
- "}",
- OnlyOther);
-
- verifyFormat("void topLevelNonEmpty() { return; }", OnlyOther);
-
- verifyFormat("class C {\n"
- " int inlineEmpty() {\n"
- " }\n"
- " int inlineNonempty() {\n"
- " return 42;\n"
- " }\n"
- "};",
- OnlyOther);
}
TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
>From 9917b99411affd232ccf9a2409aedb1e73d287d6 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Sat, 17 May 2025 14:13:53 -0700
Subject: [PATCH 12/17] fixed PR comments
---
.gitignore | 1 -
clang/include/clang/Format/Format.h | 12 ++++
clang/lib/Format/Format.cpp | 46 +++----------
clang/lib/Format/UnwrappedLineFormatter.cpp | 3 +-
clang/unittests/Format/ConfigParseTest.cpp | 20 ++----
clang/unittests/Format/FormatTest.cpp | 76 ++++++---------------
clang/unittests/Format/FormatTestCSharp.cpp | 4 +-
clang/unittests/Format/FormatTestJS.cpp | 26 ++-----
clang/unittests/Format/FormatTestJava.cpp | 4 +-
9 files changed, 61 insertions(+), 131 deletions(-)
diff --git a/.gitignore b/.gitignore
index 2b4aa551d06c0..a84268a7f6863 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,4 +73,3 @@ pythonenv*
/clang/utils/analyzer/projects/*/RefScanBuildResults
# automodapi puts generated documentation files here.
/lldb/docs/python_api/
-clang-build/
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 7ee954606718b..af88588fd164a 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -935,6 +935,18 @@ struct FormatStyle {
ShortFunctionStyle(bool Empty, bool Inline, bool Other)
: Empty(Empty), Inline(Inline), Other(Other) {}
bool isAll() const { return Empty && Inline && Other; }
+ static ShortFunctionStyle setEmptyOnly() {
+ return ShortFunctionStyle(true, false, false);
+ }
+ static ShortFunctionStyle setEmptyAndInline() {
+ return ShortFunctionStyle(true, true, false);
+ }
+ static ShortFunctionStyle setInlineOnly() {
+ return ShortFunctionStyle(false, true, false);
+ }
+ static ShortFunctionStyle setAll() {
+ return ShortFunctionStyle(true, true, true);
+ }
};
/// Dependent on the value, ``int f() { return 0; }`` can be put on a
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 859b19fe7d3e4..bd439eca7ace9 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -626,27 +626,17 @@ template <> struct MappingTraits<FormatStyle::ShortFunctionStyle> {
static void enumInput(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
IO.enumCase(Value, "None", FormatStyle::ShortFunctionStyle({}));
IO.enumCase(Value, "Empty",
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false}));
+ FormatStyle::ShortFunctionStyle::setEmptyOnly());
IO.enumCase(Value, "Inline",
FormatStyle::ShortFunctionStyle({/*Empty=*/true,
/*Inline=*/true,
/*Other=*/false}));
IO.enumCase(Value, "InlineOnly",
- FormatStyle::ShortFunctionStyle({/*Empty=*/false,
- /*Inline=*/true,
- /*Other=*/false}));
- IO.enumCase(Value, "All",
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true}));
+ FormatStyle::ShortFunctionStyle::setInlineOnly());
+ IO.enumCase(Value, "All", FormatStyle::ShortFunctionStyle::setAll());
// For backward compatibility.
- IO.enumCase(Value, "true",
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true}));
+ IO.enumCase(Value, "true", FormatStyle::ShortFunctionStyle::setAll());
IO.enumCase(Value, "false", FormatStyle::ShortFunctionStyle({}));
}
@@ -1534,9 +1524,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AllowShortCompoundRequirementOnASingleLine = true;
LLVMStyle.AllowShortEnumsOnASingleLine = true;
LLVMStyle.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
@@ -1825,9 +1813,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.AlignTrailingComments = {};
GoogleStyle.AlignTrailingComments.Kind = FormatStyle::TCAS_Never;
GoogleStyle.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyOnly();
GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
@@ -1838,9 +1824,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
GoogleStyle.AlignOperands = FormatStyle::OAS_DontAlign;
GoogleStyle.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyOnly();
// TODO: still under discussion whether to switch to SLS_All.
GoogleStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
@@ -1858,9 +1842,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.SpacesInContainerLiterals = false;
} else if (Language == FormatStyle::LK_Proto) {
GoogleStyle.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyOnly();
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
// This affects protocol buffer options specifications and text protos.
// Text protos are currently mostly formatted inside C++ raw string literals
@@ -1880,9 +1862,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
tooling::IncludeStyle::IBS_Preserve;
} else if (Language == FormatStyle::LK_CSharp) {
GoogleStyle.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyOnly();
GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
GoogleStyle.BreakStringLiterals = false;
GoogleStyle.ColumnLimit = 100;
@@ -1942,9 +1922,7 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
} else {
ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
ChromiumStyle.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline();
ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
ChromiumStyle.BinPackParameters = FormatStyle::BPPS_OnePerLine;
@@ -1959,9 +1937,7 @@ FormatStyle getMozillaStyle() {
FormatStyle MozillaStyle = getLLVMStyle();
MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
MozillaStyle.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline();
MozillaStyle.AlwaysBreakAfterDefinitionReturnType =
FormatStyle::DRTBS_TopLevel;
MozillaStyle.BinPackArguments = false;
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 8e344c820e119..722690108d2fa 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -299,7 +299,8 @@ class LineJoiner {
return true;
}
- if (Style.AllowShortFunctionsOnASingleLine.Inline) {
+ if (Style.AllowShortFunctionsOnASingleLine.Inline &&
+ !Style.AllowShortFunctionsOnASingleLine.Other) {
// Just checking TheLine->Level != 0 is not enough, because it
// provokes treating functions inside indented namespaces as short.
if (Style.isJavaScript() && TheLine->Last->is(TT_FunctionLBrace))
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 6612c3672837d..96686761cb9d6 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -624,24 +624,16 @@ TEST(ConfigParseTest, ParsesConfiguration) {
FormatStyle::ShortFunctionStyle({}));
CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false}));
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline());
CHECK_PARSE("AllowShortFunctionsOnASingleLine: Empty",
AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false}));
+ FormatStyle::ShortFunctionStyle::setEmptyOnly());
CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true}));
+ FormatStyle::ShortFunctionStyle::setAll());
CHECK_PARSE("AllowShortFunctionsOnASingleLine: InlineOnly",
AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle({/*Empty=*/false,
- /*Inline=*/true,
- /*Other=*/false}));
+ FormatStyle::ShortFunctionStyle::setInlineOnly());
// For backward compatibility:
CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
@@ -649,9 +641,7 @@ TEST(ConfigParseTest, ParsesConfiguration) {
FormatStyle::ShortFunctionStyle({}));
CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true}));
+ FormatStyle::ShortFunctionStyle::setAll());
Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
CHECK_PARSE("AllowShortLambdasOnASingleLine: None",
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index ed1582d3417c4..c90f002fec63b 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -389,9 +389,7 @@ TEST_F(FormatTest, RemovesEmptyLines) {
FormatStyle Style = getLLVMStyle();
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
Style.MaxEmptyLinesToKeep = 2;
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
Style.BraceWrapping.AfterClass = true;
@@ -3381,9 +3379,7 @@ TEST_F(FormatTest, MultiLineControlStatements) {
Style.BraceWrapping.AfterStruct = false;
Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_MultiLine;
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
Style.ColumnLimit = 80;
verifyFormat("void shortfunction() { bar(); }", Style);
verifyFormat("struct T shortfunction() { return bar(); }", Style);
@@ -3405,9 +3401,7 @@ TEST_F(FormatTest, MultiLineControlStatements) {
Style.BraceWrapping.AfterFunction = false;
Style.BraceWrapping.AfterStruct = true;
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
verifyFormat("void shortfunction() { bar(); }", Style);
verifyFormat("struct T shortfunction() { return bar(); }", Style);
verifyFormat("struct T\n"
@@ -4210,9 +4204,7 @@ TEST_F(FormatTest, FormatsNamespaces) {
FormatStyle ShortInlineFunctions = getLLVMStyle();
ShortInlineFunctions.NamespaceIndentation = FormatStyle::NI_All;
ShortInlineFunctions.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline();
verifyFormat("namespace {\n"
" void f() {\n"
" return;\n"
@@ -8349,9 +8341,7 @@ TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
Style.ColumnLimit = 80;
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
Style.ConstructorInitializerIndentWidth = 2;
verifyFormat("SomeClass::Constructor() : a(a), b(b), c(c) {}", Style);
verifyFormat("SomeClass::Constructor() :\n"
@@ -15007,9 +14997,7 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) {
FormatStyle MergeEmptyOnly = getLLVMStyle();
MergeEmptyOnly.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyOnly();
verifyFormat("class C {\n"
" int f() {}\n"
"};",
@@ -15039,9 +15027,7 @@ TEST_F(FormatTest, PullEmptyFunctionDefinitionsIntoSingleLine) {
TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
FormatStyle MergeInlineOnly = getLLVMStyle();
MergeInlineOnly.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline();
verifyFormat("class C {\n"
" int f() { return 42; }\n"
"};",
@@ -15146,9 +15132,7 @@ TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
TEST_F(FormatTest, CustomShortFunctionOptions) {
FormatStyle CustomEmpty = getLLVMStyle();
CustomEmpty.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyOnly();
// Empty functions should be on a single line
verifyFormat("int f() {}", CustomEmpty);
@@ -15185,9 +15169,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
// Test with Inline = true, All = false
FormatStyle CustomInline = getLLVMStyle();
CustomInline.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/false,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setInlineOnly();
verifyFormat("class C {\n"
" int f() {}\n"
@@ -15212,9 +15194,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
// Test with All = true
FormatStyle CustomAll = getLLVMStyle();
CustomAll.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
// All functions should be on a single line if they fit
verifyFormat("int f() { return 42; }", CustomAll);
@@ -15233,9 +15213,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
// Test various combinations
FormatStyle CustomMixed = getLLVMStyle();
CustomMixed.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline();
// Empty functions should be on a single line
verifyFormat("int f() {}", CustomMixed);
@@ -15260,9 +15238,7 @@ TEST_F(FormatTest, CustomShortFunctionOptions) {
TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
FormatStyle MergeInlineOnly = getLLVMStyle();
MergeInlineOnly.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/false,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setInlineOnly();
verifyFormat("class C {\n"
" int f() { return 42; }\n"
"};",
@@ -15334,9 +15310,7 @@ TEST_F(FormatTest, SplitEmptyFunction) {
Style);
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyOnly();
verifyFormat("int f() {}", Style);
verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
"{}",
@@ -15348,9 +15322,7 @@ TEST_F(FormatTest, SplitEmptyFunction) {
Style);
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline();
verifyFormat("class Foo {\n"
" int f() {}\n"
"};",
@@ -15359,6 +15331,10 @@ TEST_F(FormatTest, SplitEmptyFunction) {
" int f() { return 0; }\n"
"};",
Style);
+ verifyFormat("class Foo {\n"
+ " int f() { return 0; }\n"
+ "};",
+ Style);
verifyFormat("class Foo {\n"
" int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
" {}\n"
@@ -15373,9 +15349,7 @@ TEST_F(FormatTest, SplitEmptyFunction) {
Style);
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
verifyFormat("int f() {}", Style);
verifyFormat("int f() { return 0; }", Style);
verifyFormat("int aaaaaaaaaaaaaa(int bbbbbbbbbbbbbb)\n"
@@ -15421,9 +15395,7 @@ TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
TEST_F(FormatTest, KeepShortFunctionAfterPPElse) {
FormatStyle Style = getLLVMStyle();
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
verifyFormat("#ifdef A\n"
"int f() {}\n"
"#else\n"
@@ -21546,9 +21518,7 @@ TEST_F(FormatTest, WhitesmithsBraceBreaking) {
// Make a few changes to the style for testing purposes
WhitesmithsBraceStyle.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyOnly();
WhitesmithsBraceStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None;
// FIXME: this test case can't decide whether there should be a blank line
@@ -23105,9 +23075,7 @@ TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
Style.ColumnLimit = 80;
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
Style.ConstructorInitializerIndentWidth = 2;
verifyFormat("SomeClass::Constructor()\n"
" : a(a)\n"
diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp
index 22c757509f5fb..da39620916ba4 100644
--- a/clang/unittests/Format/FormatTestCSharp.cpp
+++ b/clang/unittests/Format/FormatTestCSharp.cpp
@@ -1661,9 +1661,7 @@ TEST_F(FormatTestCSharp, ShortFunctions) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
Style.NamespaceIndentation = FormatStyle::NI_All;
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline();
verifyFormat("interface Interface {\n"
" void f() { return; }\n"
"};",
diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp
index 03e55e4498fd4..fe2dc6f404fe0 100644
--- a/clang/unittests/Format/FormatTestJS.cpp
+++ b/clang/unittests/Format/FormatTestJS.cpp
@@ -1016,9 +1016,7 @@ TEST_F(FormatTestJS, TrailingCommaInsertion) {
TEST_F(FormatTestJS, FunctionLiterals) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline();
verifyFormat("doFoo(function() {});");
verifyFormat("doFoo(function() { return 1; });", Style);
verifyFormat("var func = function() {\n"
@@ -1132,9 +1130,7 @@ TEST_F(FormatTestJS, DontWrapEmptyLiterals) {
TEST_F(FormatTestJS, InliningFunctionLiterals) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline();
verifyFormat("var func = function() {\n"
" return 1;\n"
"};",
@@ -1150,9 +1146,7 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
Style);
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
verifyFormat("var func = function() { return 1; };", Style);
verifyFormat("var func = doSomething(function() { return 1; });", Style);
verifyFormat(
@@ -1186,9 +1180,7 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
Style);
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/false,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyOnly();
verifyFormat("var func = function() {\n"
" return 1;\n"
"};",
@@ -1197,10 +1189,8 @@ TEST_F(FormatTestJS, InliningFunctionLiterals) {
TEST_F(FormatTestJS, InliningFunctionLiteralsNew) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
- Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/false,
- /*Inline=*/false,
- /*Other=*/true});
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+ Style.AllowShortFunctionsOnASingleLine.Other = true;
verifyFormat("var func = function() { return 1; };", Style);
verifyFormat("var func = doSomething(function() {\n"
" return 1;\n"
@@ -1229,9 +1219,7 @@ TEST_F(FormatTestJS, InliningFunctionLiteralsNew) {
TEST_F(FormatTestJS, MultipleFunctionLiterals) {
FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/true});
+ FormatStyle::ShortFunctionStyle::setAll();
verifyFormat("promise.then(\n"
" function success() {\n"
" doFoo();\n"
diff --git a/clang/unittests/Format/FormatTestJava.cpp b/clang/unittests/Format/FormatTestJava.cpp
index 77ca00d0fd132..581661f131a6d 100644
--- a/clang/unittests/Format/FormatTestJava.cpp
+++ b/clang/unittests/Format/FormatTestJava.cpp
@@ -597,9 +597,7 @@ TEST_F(FormatTestJava, RetainsLogicalShifts) {
TEST_F(FormatTestJava, ShortFunctions) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_Java);
Style.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false});
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline();
verifyFormat("enum Enum {\n"
" E1,\n"
" E2;\n"
>From d7ad2a8e97e51307b553403df6441535998ee478 Mon Sep 17 00:00:00 2001
From: Ivan Rymarchyk <>
Date: Sat, 17 May 2025 14:19:33 -0700
Subject: [PATCH 13/17] added one forgotten change
---
clang/lib/Format/Format.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index bd439eca7ace9..77eda64b626d6 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -628,9 +628,7 @@ template <> struct MappingTraits<FormatStyle::ShortFunctionStyle> {
IO.enumCase(Value, "Empty",
FormatStyle::ShortFunctionStyle::setEmptyOnly());
IO.enumCase(Value, "Inline",
- FormatStyle::ShortFunctionStyle({/*Empty=*/true,
- /*Inline=*/true,
- /*Other=*/false}));
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline());
IO.enumCase(Value, "InlineOnly",
FormatStyle::ShortFunctionStyle::setInlineOnly());
IO.enumCase(Value, "All", FormatStyle::ShortFunctionStyle::setAll());
>From 8cdab54443a1121b9b5cda47117d09c333bd7e7b Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:04:22 -0700
Subject: [PATCH 14/17] Refactor ShortFunctionStyle initialization
---
clang/lib/Format/Format.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index a5c597d5a0613..adfe4ba982453 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -733,7 +733,7 @@ template <> struct ScalarEnumerationTraits<FormatStyle::ShortBlockStyle> {
template <> struct MappingTraits<FormatStyle::ShortFunctionStyle> {
static void enumInput(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
- IO.enumCase(Value, "None", FormatStyle::ShortFunctionStyle({}));
+ IO.enumCase(Value, "None", FormatStyle::ShortFunctionStyle());
IO.enumCase(Value, "Empty",
FormatStyle::ShortFunctionStyle::setEmptyOnly());
IO.enumCase(Value, "Inline",
@@ -744,7 +744,7 @@ template <> struct MappingTraits<FormatStyle::ShortFunctionStyle> {
// For backward compatibility.
IO.enumCase(Value, "true", FormatStyle::ShortFunctionStyle::setAll());
- IO.enumCase(Value, "false", FormatStyle::ShortFunctionStyle({}));
+ IO.enumCase(Value, "false", FormatStyle::ShortFunctionStyle());
}
static void mapping(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
@@ -2273,7 +2273,7 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
Style.BraceWrapping.BeforeWhile = false;
Style.PenaltyReturnTypeOnItsOwnLine = 1000;
Style.AllowShortEnumsOnASingleLine = false;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
Style.AllowShortCaseLabelsOnASingleLine = false;
Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
Style.AllowShortLoopsOnASingleLine = false;
>From c68afc2fb4b3ded12f2b759965733c14c4cf89a8 Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:07:15 -0700
Subject: [PATCH 15/17] Update fmt.Println message from 'Hello' to 'Goodbye'
---
.../Format/DefinitionBlockSeparatorTest.cpp | 2372 +++++++++++++----
1 file changed, 1795 insertions(+), 577 deletions(-)
diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
index 895ab0fe73cc9..8cd0dd840acf8 100644
--- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
+++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
@@ -1,4 +1,4 @@
-//===- DefinitionBlockSeparatorTest.cpp - Formatting unit tests -----------===//
+//===- unittest/Format/ConfigParseTest.cpp - Config parsing unit tests ----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,614 +6,1832 @@
//
//===----------------------------------------------------------------------===//
-#include "FormatTestUtils.h"
#include "clang/Format/Format.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "gtest/gtest.h"
-#define DEBUG_TYPE "definition-block-separator-test"
-
namespace clang {
namespace format {
namespace {
-class DefinitionBlockSeparatorTest : public testing::Test {
-protected:
- static std::string
- separateDefinitionBlocks(StringRef Code,
- const std::vector<tooling::Range> &Ranges,
- const FormatStyle &Style = getLLVMStyle()) {
- LLVM_DEBUG(llvm::errs() << "---\n");
- LLVM_DEBUG(llvm::errs() << Code << "\n\n");
- tooling::Replacements Replaces = reformat(Style, Code, Ranges, "<stdin>");
- auto Result = applyAllReplacements(Code, Replaces);
- EXPECT_TRUE(static_cast<bool>(Result));
- LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
- return *Result;
- }
-
- static std::string
- separateDefinitionBlocks(StringRef Code,
- const FormatStyle &Style = getLLVMStyle()) {
- return separateDefinitionBlocks(
- Code,
- /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
- }
-
- static void _verifyFormat(const char *File, int Line, StringRef Code,
- const FormatStyle &Style = getLLVMStyle(),
- StringRef ExpectedCode = "", bool Inverse = true) {
- testing::ScopedTrace t(File, Line, testing::Message() << Code.str());
- bool HasOriginalCode = true;
- if (ExpectedCode == "") {
- ExpectedCode = Code;
- HasOriginalCode = false;
- }
-
- EXPECT_EQ(ExpectedCode, separateDefinitionBlocks(ExpectedCode, Style))
- << "Expected code is not stable";
- if (Inverse) {
- FormatStyle InverseStyle = Style;
- if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always)
- InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
- else
- InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
- EXPECT_NE(ExpectedCode,
- separateDefinitionBlocks(ExpectedCode, InverseStyle))
- << "Inverse formatting makes no difference";
- }
- std::string CodeToFormat =
- HasOriginalCode ? Code.str() : removeEmptyLines(Code);
- std::string Result = separateDefinitionBlocks(CodeToFormat, Style);
- EXPECT_EQ(ExpectedCode, Result) << "Test failed. Formatted:\n" << Result;
- }
-
- static std::string removeEmptyLines(StringRef Code) {
- std::string Result = "";
- for (auto Char : Code.str()) {
- if (Result.size()) {
- auto LastChar = Result.back();
- if ((Char == '\n' && LastChar == '\n') ||
- (Char == '\r' && (LastChar == '\r' || LastChar == '\n'))) {
- continue;
- }
- }
- Result.push_back(Char);
- }
- return Result;
- }
-};
-
-#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)
-
-TEST_F(DefinitionBlockSeparatorTest, Basic) {
- FormatStyle Style = getLLVMStyle();
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
- verifyFormat("int foo(int i, int j) {\n"
- " int r = i + j;\n"
- " return r;\n"
- "}\n"
- "\n"
- "int bar(int j, int k) {\n"
- " int r = j + k;\n"
- " return r;\n"
- "}",
- Style);
-
- verifyFormat("struct foo {\n"
- " int i, j;\n"
- "};\n"
- "\n"
- "struct bar {\n"
- " int j, k;\n"
- "};",
- Style);
-
- verifyFormat("union foo {\n"
- " int i, j;\n"
- "};\n"
- "\n"
- "union bar {\n"
- " int j, k;\n"
- "};",
- Style);
-
- verifyFormat("class foo {\n"
- " int i, j;\n"
- "};\n"
- "\n"
- "class bar {\n"
- " int j, k;\n"
- "};",
- Style);
-
- verifyFormat("namespace foo {\n"
- "int i, j;\n"
- "}\n"
- "\n"
- "namespace bar {\n"
- "int j, k;\n"
- "}",
- Style);
-
- verifyFormat("enum Foo { FOO, BAR };\n"
- "\n"
- "enum Bar { FOOBAR, BARFOO };",
- Style);
-
- FormatStyle BreakAfterReturnTypeStyle = Style;
- BreakAfterReturnTypeStyle.BreakAfterReturnType = FormatStyle::RTBS_All;
- // Test uppercased long typename
- verifyFormat("class Foo {\n"
- " void\n"
- " Bar(int t, int p) {\n"
- " int r = t + p;\n"
- " return r;\n"
- " }\n"
- "\n"
- " HRESULT\n"
- " Foobar(int t, int p) {\n"
- " int r = t * p;\n"
- " return r;\n"
- " }\n"
- "}",
- BreakAfterReturnTypeStyle);
+void dropDiagnosticHandler(const llvm::SMDiagnostic &, void *) {}
+FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); }
+
+#define EXPECT_ALL_STYLES_EQUAL(Styles) \
+ for (size_t i = 1; i < Styles.size(); ++i) \
+ EXPECT_EQ(Styles[0], Styles[i]) \
+ << "Style #" << i << " of " << Styles.size() << " differs from Style #0"
+
+TEST(ConfigParseTest, GetsPredefinedStyleByName) {
+ SmallVector<FormatStyle, 3> Styles;
+ Styles.resize(3);
+
+ Styles[0] = getLLVMStyle();
+ EXPECT_TRUE(getPredefinedStyle("LLVM", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("lLvM", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ Styles[0] = getGoogleStyle();
+ EXPECT_TRUE(getPredefinedStyle("Google", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("gOOgle", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript);
+ EXPECT_TRUE(
+ getPredefinedStyle("Google", FormatStyle::LK_JavaScript, &Styles[1]));
+ EXPECT_TRUE(
+ getPredefinedStyle("gOOgle", FormatStyle::LK_JavaScript, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ Styles[0] = getChromiumStyle(FormatStyle::LK_Cpp);
+ EXPECT_TRUE(getPredefinedStyle("Chromium", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("cHRoMiUM", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ Styles[0] = getMozillaStyle();
+ EXPECT_TRUE(getPredefinedStyle("Mozilla", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("moZILla", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ Styles[0] = getWebKitStyle();
+ EXPECT_TRUE(getPredefinedStyle("WebKit", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("wEbKit", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ Styles[0] = getGNUStyle();
+ EXPECT_TRUE(getPredefinedStyle("GNU", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(getPredefinedStyle("gnU", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ Styles[0] = getClangFormatStyle();
+ EXPECT_TRUE(
+ getPredefinedStyle("clang-format", FormatStyle::LK_Cpp, &Styles[1]));
+ EXPECT_TRUE(
+ getPredefinedStyle("Clang-format", FormatStyle::LK_Cpp, &Styles[2]));
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ EXPECT_FALSE(getPredefinedStyle("qwerty", FormatStyle::LK_Cpp, &Styles[0]));
}
-TEST_F(DefinitionBlockSeparatorTest, FormatConflict) {
- FormatStyle Style = getLLVMStyle();
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
- StringRef Code = "class Test {\n"
- "public:\n"
- " static void foo() {\n"
- " int t;\n"
- " return 1;\n"
- " }\n"
- "};";
- std::vector<tooling::Range> Ranges = {1, tooling::Range(0, Code.size())};
- EXPECT_EQ(reformat(Style, Code, Ranges, "<stdin>").size(), 0u);
+TEST(ConfigParseTest, GetsCorrectBasedOnStyle) {
+ SmallVector<FormatStyle, 8> Styles;
+ Styles.resize(2);
+
+ Styles[0] = getGoogleStyle();
+ Styles[1] = getLLVMStyle();
+ EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
+ EXPECT_ALL_STYLES_EQUAL(Styles);
+
+ Styles.resize(5);
+ Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript);
+ Styles[1] = getLLVMStyle();
+ Styles[1].Language = FormatStyle::LK_JavaScript;
+ EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
+
+ Styles[2] = getLLVMStyle();
+ Styles[2].Language = FormatStyle::LK_JavaScript;
+ EXPECT_EQ(0, parseConfiguration("Language: JavaScript\n"
+ "BasedOnStyle: Google",
+ &Styles[2])
+ .value());
+
+ Styles[3] = getLLVMStyle();
+ Styles[3].Language = FormatStyle::LK_JavaScript;
+ EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google\n"
+ "Language: JavaScript",
+ &Styles[3])
+ .value());
+
+ Styles[4] = getLLVMStyle();
+ Styles[4].Language = FormatStyle::LK_JavaScript;
+ EXPECT_EQ(0, parseConfiguration("---\n"
+ "BasedOnStyle: LLVM\n"
+ "IndentWidth: 123\n"
+ "---\n"
+ "BasedOnStyle: Google\n"
+ "Language: JavaScript",
+ &Styles[4])
+ .value());
+ EXPECT_ALL_STYLES_EQUAL(Styles);
}
-TEST_F(DefinitionBlockSeparatorTest, CommentBlock) {
- FormatStyle Style = getLLVMStyle();
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
- std::string Prefix = "enum Foo { FOO, BAR };\n"
- "\n"
- "/*\n"
- "test1\n"
- "test2\n"
- "*/\n"
- "int foo(int i, int j) {\n"
- " int r = i + j;\n"
- " return r;\n"
- "}\n";
- std::string Suffix = "enum Bar { FOOBAR, BARFOO };\n"
- "\n"
- "/* Comment block in one line*/\n"
- "int bar3(int j, int k) {\n"
- " // A comment\n"
- " int r = j % k;\n"
- " return r;\n"
- "}\n";
- std::string CommentedCode = "/*\n"
- "int bar2(int j, int k) {\n"
- " int r = j / k;\n"
- " return r;\n"
- "}\n"
- "*/\n";
- verifyFormat(removeEmptyLines(Prefix) + "\n" + CommentedCode + "\n" +
- removeEmptyLines(Suffix),
- Style, Prefix + "\n" + CommentedCode + "\n" + Suffix);
- verifyFormat(removeEmptyLines(Prefix) + "\n" + CommentedCode +
- removeEmptyLines(Suffix),
- Style, Prefix + "\n" + CommentedCode + Suffix);
+#define CHECK_PARSE_BOOL_FIELD(FIELD, CONFIG_NAME) \
+ Style.FIELD = false; \
+ EXPECT_EQ(0, parseConfiguration(CONFIG_NAME ": true", &Style).value()); \
+ EXPECT_TRUE(Style.FIELD); \
+ EXPECT_EQ(0, parseConfiguration(CONFIG_NAME ": false", &Style).value()); \
+ EXPECT_FALSE(Style.FIELD)
+
+#define CHECK_PARSE_BOOL(FIELD) CHECK_PARSE_BOOL_FIELD(FIELD, #FIELD)
+
+#define CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, CONFIG_NAME) \
+ Style.STRUCT.FIELD = false; \
+ EXPECT_EQ(0, \
+ parseConfiguration(#STRUCT ":\n " CONFIG_NAME ": true", &Style) \
+ .value()); \
+ EXPECT_TRUE(Style.STRUCT.FIELD); \
+ EXPECT_EQ(0, \
+ parseConfiguration(#STRUCT ":\n " CONFIG_NAME ": false", &Style) \
+ .value()); \
+ EXPECT_FALSE(Style.STRUCT.FIELD)
+
+#define CHECK_PARSE_NESTED_BOOL(STRUCT, FIELD) \
+ CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, #FIELD)
+
+#define CHECK_PARSE(TEXT, FIELD, VALUE) \
+ EXPECT_NE(VALUE, Style.FIELD) << "Initial value already the same!"; \
+ EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value()); \
+ EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"
+
+#define CHECK_PARSE_INT(FIELD) CHECK_PARSE(#FIELD ": -1234", FIELD, -1234)
+
+#define CHECK_PARSE_UNSIGNED(FIELD) CHECK_PARSE(#FIELD ": 1234", FIELD, 1234u)
+
+#define CHECK_PARSE_LIST(FIELD) \
+ CHECK_PARSE(#FIELD ": [foo]", FIELD, std::vector<std::string>{"foo"})
+
+#define CHECK_PARSE_NESTED_VALUE(TEXT, STRUCT, FIELD, VALUE) \
+ EXPECT_NE(VALUE, Style.STRUCT.FIELD) << "Initial value already the same!"; \
+ EXPECT_EQ(0, parseConfiguration(#STRUCT ":\n " TEXT, &Style).value()); \
+ EXPECT_EQ(VALUE, Style.STRUCT.FIELD) << "Unexpected value after parsing!"
+
+TEST(ConfigParseTest, ParsesConfigurationBools) {
+ FormatStyle Style = {};
+ Style.Language = FormatStyle::LK_Cpp;
+ CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine);
+ CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
+ CHECK_PARSE_BOOL(AllowBreakBeforeQtProperty);
+ CHECK_PARSE_BOOL(AllowShortCaseExpressionOnASingleLine);
+ CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);
+ CHECK_PARSE_BOOL(AllowShortCompoundRequirementOnASingleLine);
+ CHECK_PARSE_BOOL(AllowShortEnumsOnASingleLine);
+ CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
+ CHECK_PARSE_BOOL(AllowShortNamespacesOnASingleLine);
+ CHECK_PARSE_BOOL(BinPackArguments);
+ CHECK_PARSE_BOOL(BinPackLongBracedList);
+ CHECK_PARSE_BOOL(BreakAdjacentStringLiterals);
+ CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations);
+ CHECK_PARSE_BOOL(BreakAfterOpenBracketBracedList);
+ CHECK_PARSE_BOOL(BreakAfterOpenBracketFunction);
+ CHECK_PARSE_BOOL(BreakAfterOpenBracketIf);
+ CHECK_PARSE_BOOL(BreakAfterOpenBracketLoop);
+ CHECK_PARSE_BOOL(BreakAfterOpenBracketSwitch);
+ CHECK_PARSE_BOOL(BreakBeforeCloseBracketBracedList);
+ CHECK_PARSE_BOOL(BreakBeforeCloseBracketFunction);
+ CHECK_PARSE_BOOL(BreakBeforeCloseBracketIf);
+ CHECK_PARSE_BOOL(BreakBeforeCloseBracketLoop);
+ CHECK_PARSE_BOOL(BreakBeforeCloseBracketSwitch);
+ CHECK_PARSE_BOOL(BreakBeforeTemplateCloser);
+ CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
+ CHECK_PARSE_BOOL(BreakStringLiterals);
+ CHECK_PARSE_BOOL(CompactNamespaces);
+ CHECK_PARSE_BOOL(DerivePointerAlignment);
+ CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding");
+ CHECK_PARSE_BOOL(DisableFormat);
+ CHECK_PARSE_BOOL(IndentAccessModifiers);
+ CHECK_PARSE_BOOL(IndentCaseBlocks);
+ CHECK_PARSE_BOOL(IndentCaseLabels);
+ CHECK_PARSE_BOOL(IndentExportBlock);
+ CHECK_PARSE_BOOL(IndentRequiresClause);
+ CHECK_PARSE_BOOL_FIELD(IndentRequiresClause, "IndentRequires");
+ CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+ CHECK_PARSE_BOOL(InsertBraces);
+ CHECK_PARSE_BOOL(InsertNewlineAtEOF);
+ CHECK_PARSE_BOOL_FIELD(KeepEmptyLines.AtEndOfFile, "KeepEmptyLinesAtEOF");
+ CHECK_PARSE_BOOL_FIELD(KeepEmptyLines.AtStartOfBlock,
+ "KeepEmptyLinesAtTheStartOfBlocks");
+ CHECK_PARSE_BOOL(KeepFormFeed);
+ CHECK_PARSE_BOOL(ObjCSpaceAfterMethodDeclarationPrefix);
+ CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
+ CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
+ CHECK_PARSE_BOOL(RemoveBracesLLVM);
+ CHECK_PARSE_BOOL(RemoveEmptyLinesInUnwrappedLines);
+ CHECK_PARSE_BOOL(RemoveSemicolon);
+ CHECK_PARSE_BOOL(SkipMacroDefinitionBody);
+ CHECK_PARSE_BOOL(SpacesInSquareBrackets);
+ CHECK_PARSE_BOOL(SpacesInContainerLiterals);
+ CHECK_PARSE_BOOL(SpaceAfterCStyleCast);
+ CHECK_PARSE_BOOL(SpaceAfterTemplateKeyword);
+ CHECK_PARSE_BOOL(SpaceAfterOperatorKeyword);
+ CHECK_PARSE_BOOL(SpaceAfterLogicalNot);
+ CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators);
+ CHECK_PARSE_BOOL(SpaceBeforeCaseColon);
+ CHECK_PARSE_BOOL(SpaceBeforeCpp11BracedList);
+ CHECK_PARSE_BOOL(SpaceBeforeCtorInitializerColon);
+ CHECK_PARSE_BOOL(SpaceBeforeInheritanceColon);
+ CHECK_PARSE_BOOL(SpaceBeforeJsonColon);
+ CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon);
+ CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets);
+ CHECK_PARSE_BOOL(VerilogBreakBetweenInstancePorts);
+
+ CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, Enabled);
+ CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements,
+ AcrossEmptyLines);
+ CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AcrossComments);
+ CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseArrows);
+ CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseColons);
+ CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Empty);
+ CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Inline);
+ CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Other);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterEnum);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterFunction);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterNamespace);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterObjCDeclaration);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterStruct);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterUnion);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterExternBlock);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeCatch);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeElse);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeLambdaBody);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeWhile);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyNamespace);
+ CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtEndOfFile);
+ CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtStartOfBlock);
+ CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtStartOfFile);
+ CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterControlStatements);
+ CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterForeachMacros);
+ CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions,
+ AfterFunctionDeclarationName);
+ CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions,
+ AfterFunctionDefinitionName);
+ CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros);
+ CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterNot);
+ CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
+ CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterPlacementOperator);
+ CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
+ CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, ExceptDoubleParentheses);
+ CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts);
+ CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
+ CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
+ CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
+ CHECK_PARSE_NESTED_BOOL(SortIncludes, Enabled);
+ CHECK_PARSE_NESTED_BOOL(SortIncludes, IgnoreCase);
+ CHECK_PARSE_NESTED_BOOL(SortIncludes, IgnoreExtension);
}
-TEST_F(DefinitionBlockSeparatorTest, UntouchBlockStartStyle) {
- // Returns a std::pair of two strings, with the first one for passing into
- // Always test and the second one be the expected result of the first string.
- auto MakeUntouchTest = [&](std::string BlockHeader, std::string BlockChanger,
- std::string BlockFooter, bool BlockEndNewLine) {
- std::string CodePart1 = "enum Foo { FOO, BAR };\n"
- "\n"
- "/*\n"
- "test1\n"
- "test2\n"
- "*/\n"
- "int foo(int i, int j) {\n"
- " int r = i + j;\n"
- " return r;\n"
- "}\n";
- std::string CodePart2 = "/* Comment block in one line*/\n"
- "enum Bar { FOOBAR, BARFOO };\n"
- "\n"
- "int bar3(int j, int k) {\n"
- " // A comment\n"
- " int r = j % k;\n"
- " return r;\n"
- "}\n";
- std::string CodePart3 = "int bar2(int j, int k) {\n"
- " int r = j / k;\n"
- " return r;\n"
- "}\n";
- std::string ConcatAll = BlockHeader + CodePart1 + BlockChanger + CodePart2 +
- BlockFooter + (BlockEndNewLine ? "\n" : "") +
- CodePart3;
- return std::make_pair(BlockHeader + removeEmptyLines(CodePart1) +
- BlockChanger + removeEmptyLines(CodePart2) +
- BlockFooter + removeEmptyLines(CodePart3),
- ConcatAll);
+#undef CHECK_PARSE_BOOL
+
+TEST(ConfigParseTest, ParsesConfigurationIntegers) {
+ FormatStyle Style = {};
+ Style.Language = FormatStyle::LK_Cpp;
+
+ CHECK_PARSE_INT(AccessModifierOffset);
+ CHECK_PARSE_INT(BracedInitializerIndentWidth);
+ CHECK_PARSE_INT(PPIndentWidth);
+
+ CHECK_PARSE_UNSIGNED(ColumnLimit);
+ CHECK_PARSE_UNSIGNED(ConstructorInitializerIndentWidth);
+ CHECK_PARSE_UNSIGNED(ContinuationIndentWidth);
+ CHECK_PARSE_UNSIGNED(IndentWidth);
+ CHECK_PARSE_UNSIGNED(MaxEmptyLinesToKeep);
+ CHECK_PARSE_UNSIGNED(ObjCBlockIndentWidth);
+ CHECK_PARSE_UNSIGNED(PenaltyBreakAssignment);
+ CHECK_PARSE_UNSIGNED(PenaltyBreakBeforeFirstCallParameter);
+ CHECK_PARSE_UNSIGNED(PenaltyBreakBeforeMemberAccess);
+ CHECK_PARSE_UNSIGNED(PenaltyBreakComment);
+ CHECK_PARSE_UNSIGNED(PenaltyBreakFirstLessLess);
+ CHECK_PARSE_UNSIGNED(PenaltyBreakOpenParenthesis);
+ CHECK_PARSE_UNSIGNED(PenaltyBreakScopeResolution);
+ CHECK_PARSE_UNSIGNED(PenaltyBreakString);
+ CHECK_PARSE_UNSIGNED(PenaltyBreakTemplateDeclaration);
+ CHECK_PARSE_UNSIGNED(PenaltyExcessCharacter);
+ CHECK_PARSE_UNSIGNED(PenaltyIndentedWhitespace);
+ CHECK_PARSE_UNSIGNED(PenaltyReturnTypeOnItsOwnLine);
+ CHECK_PARSE_UNSIGNED(ShortNamespaceLines);
+ CHECK_PARSE_UNSIGNED(SpacesBeforeTrailingComments);
+ CHECK_PARSE_UNSIGNED(TabWidth);
+}
+
+TEST(ConfigParseTest, ParsesConfiguration) {
+ FormatStyle Style = {};
+ Style.Language = FormatStyle::LK_Cpp;
+ CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$");
+ CHECK_PARSE("OneLineFormatOffRegex: // ab$", OneLineFormatOffRegex, "// ab$");
+
+ Style.QualifierAlignment = FormatStyle::QAS_Right;
+ CHECK_PARSE("QualifierAlignment: Leave", QualifierAlignment,
+ FormatStyle::QAS_Leave);
+ CHECK_PARSE("QualifierAlignment: Right", QualifierAlignment,
+ FormatStyle::QAS_Right);
+ CHECK_PARSE("QualifierAlignment: Left", QualifierAlignment,
+ FormatStyle::QAS_Left);
+ CHECK_PARSE("QualifierAlignment: Custom", QualifierAlignment,
+ FormatStyle::QAS_Custom);
+
+ Style.QualifierOrder.clear();
+ CHECK_PARSE("QualifierOrder: [ const, volatile, type ]", QualifierOrder,
+ std::vector<std::string>({"const", "volatile", "type"}));
+ Style.QualifierOrder.clear();
+ CHECK_PARSE("QualifierOrder: [const, type]", QualifierOrder,
+ std::vector<std::string>({"const", "type"}));
+ Style.QualifierOrder.clear();
+ CHECK_PARSE("QualifierOrder: [volatile, type]", QualifierOrder,
+ std::vector<std::string>({"volatile", "type"}));
+
+#define CHECK_ALIGN_CONSECUTIVE(FIELD) \
+ do { \
+ Style.FIELD.Enabled = true; \
+ CHECK_PARSE(#FIELD ": None", FIELD, \
+ FormatStyle::AlignConsecutiveStyle({})); \
+ CHECK_PARSE( \
+ #FIELD ": Consecutive", FIELD, \
+ FormatStyle::AlignConsecutiveStyle( \
+ {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \
+ /*AcrossComments=*/false, /*AlignCompound=*/false, \
+ /*AlignFunctionDeclarations=*/true, \
+ /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
+ CHECK_PARSE( \
+ #FIELD ": AcrossEmptyLines", FIELD, \
+ FormatStyle::AlignConsecutiveStyle( \
+ {/*Enabled=*/true, /*AcrossEmptyLines=*/true, \
+ /*AcrossComments=*/false, /*AlignCompound=*/false, \
+ /*AlignFunctionDeclarations=*/true, \
+ /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
+ CHECK_PARSE( \
+ #FIELD ": AcrossComments", FIELD, \
+ FormatStyle::AlignConsecutiveStyle( \
+ {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \
+ /*AcrossComments=*/true, /*AlignCompound=*/false, \
+ /*AlignFunctionDeclarations=*/true, \
+ /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
+ CHECK_PARSE( \
+ #FIELD ": AcrossEmptyLinesAndComments", FIELD, \
+ FormatStyle::AlignConsecutiveStyle( \
+ {/*Enabled=*/true, /*AcrossEmptyLines=*/true, \
+ /*AcrossComments=*/true, /*AlignCompound=*/false, \
+ /*AlignFunctionDeclarations=*/true, \
+ /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
+ /* For backwards compability, false / true should still parse */ \
+ CHECK_PARSE(#FIELD ": false", FIELD, \
+ FormatStyle::AlignConsecutiveStyle({})); \
+ CHECK_PARSE( \
+ #FIELD ": true", FIELD, \
+ FormatStyle::AlignConsecutiveStyle( \
+ {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \
+ /*AcrossComments=*/false, /*AlignCompound=*/false, \
+ /*AlignFunctionDeclarations=*/true, \
+ /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
+ \
+ CHECK_PARSE_NESTED_BOOL(FIELD, Enabled); \
+ CHECK_PARSE_NESTED_BOOL(FIELD, AcrossEmptyLines); \
+ CHECK_PARSE_NESTED_BOOL(FIELD, AcrossComments); \
+ CHECK_PARSE_NESTED_BOOL(FIELD, AlignCompound); \
+ CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionDeclarations); \
+ CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionPointers); \
+ CHECK_PARSE_NESTED_BOOL(FIELD, PadOperators); \
+ } while (false)
+
+ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveAssignments);
+ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields);
+ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveMacros);
+ CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveDeclarations);
+
+#undef CHECK_ALIGN_CONSECUTIVE
+
+ Style.PointerAlignment = FormatStyle::PAS_Middle;
+ CHECK_PARSE("PointerAlignment: Left", PointerAlignment,
+ FormatStyle::PAS_Left);
+ CHECK_PARSE("PointerAlignment: Right", PointerAlignment,
+ FormatStyle::PAS_Right);
+ CHECK_PARSE("PointerAlignment: Middle", PointerAlignment,
+ FormatStyle::PAS_Middle);
+ Style.ReferenceAlignment = FormatStyle::RAS_Middle;
+ CHECK_PARSE("ReferenceAlignment: Pointer", ReferenceAlignment,
+ FormatStyle::RAS_Pointer);
+ CHECK_PARSE("ReferenceAlignment: Left", ReferenceAlignment,
+ FormatStyle::RAS_Left);
+ CHECK_PARSE("ReferenceAlignment: Right", ReferenceAlignment,
+ FormatStyle::RAS_Right);
+ CHECK_PARSE("ReferenceAlignment: Middle", ReferenceAlignment,
+ FormatStyle::RAS_Middle);
+ // For backward compatibility:
+ CHECK_PARSE("PointerBindsToType: Left", PointerAlignment,
+ FormatStyle::PAS_Left);
+ CHECK_PARSE("PointerBindsToType: Right", PointerAlignment,
+ FormatStyle::PAS_Right);
+ CHECK_PARSE("PointerBindsToType: Middle", PointerAlignment,
+ FormatStyle::PAS_Middle);
+
+ Style.ReflowComments = FormatStyle::RCS_Always;
+ CHECK_PARSE("ReflowComments: Never", ReflowComments, FormatStyle::RCS_Never);
+ CHECK_PARSE("ReflowComments: IndentOnly", ReflowComments,
+ FormatStyle::RCS_IndentOnly);
+ CHECK_PARSE("ReflowComments: Always", ReflowComments,
+ FormatStyle::RCS_Always);
+ // For backward compatibility:
+ CHECK_PARSE("ReflowComments: false", ReflowComments, FormatStyle::RCS_Never);
+ CHECK_PARSE("ReflowComments: true", ReflowComments, FormatStyle::RCS_Always);
+
+ Style.Standard = FormatStyle::LS_Auto;
+ CHECK_PARSE("Standard: c++03", Standard, FormatStyle::LS_Cpp03);
+ CHECK_PARSE("Standard: c++11", Standard, FormatStyle::LS_Cpp11);
+ CHECK_PARSE("Standard: c++14", Standard, FormatStyle::LS_Cpp14);
+ CHECK_PARSE("Standard: c++17", Standard, FormatStyle::LS_Cpp17);
+ CHECK_PARSE("Standard: c++20", Standard, FormatStyle::LS_Cpp20);
+ CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto);
+ CHECK_PARSE("Standard: Latest", Standard, FormatStyle::LS_Latest);
+ // Legacy aliases:
+ CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03);
+ CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Latest);
+ CHECK_PARSE("Standard: C++03", Standard, FormatStyle::LS_Cpp03);
+ CHECK_PARSE("Standard: C++11", Standard, FormatStyle::LS_Cpp11);
+
+ Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
+ CHECK_PARSE("BreakBeforeBinaryOperators: NonAssignment",
+ BreakBeforeBinaryOperators, FormatStyle::BOS_NonAssignment);
+ CHECK_PARSE("BreakBeforeBinaryOperators: None", BreakBeforeBinaryOperators,
+ FormatStyle::BOS_None);
+ CHECK_PARSE("BreakBeforeBinaryOperators: All", BreakBeforeBinaryOperators,
+ FormatStyle::BOS_All);
+ // For backward compatibility:
+ CHECK_PARSE("BreakBeforeBinaryOperators: false", BreakBeforeBinaryOperators,
+ FormatStyle::BOS_None);
+ CHECK_PARSE("BreakBeforeBinaryOperators: true", BreakBeforeBinaryOperators,
+ FormatStyle::BOS_All);
+
+ Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
+ CHECK_PARSE("BreakBinaryOperations: OnePerLine", BreakBinaryOperations,
+ FormatStyle::BreakBinaryOperationsOptions(
+ {FormatStyle::BBO_OnePerLine, {}}));
+ CHECK_PARSE("BreakBinaryOperations: RespectPrecedence", BreakBinaryOperations,
+ FormatStyle::BreakBinaryOperationsOptions(
+ {FormatStyle::BBO_RespectPrecedence, {}}));
+ CHECK_PARSE(
+ "BreakBinaryOperations: Never", BreakBinaryOperations,
+ FormatStyle::BreakBinaryOperationsOptions({FormatStyle::BBO_Never, {}}));
+
+ // Structured form
+ Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
+ CHECK_PARSE("BreakBinaryOperations:\n"
+ " Default: OnePerLine",
+ BreakBinaryOperations,
+ FormatStyle::BreakBinaryOperationsOptions(
+ {FormatStyle::BBO_OnePerLine, {}}));
+
+ Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
+ EXPECT_EQ(0, parseConfiguration("BreakBinaryOperations:\n"
+ " Default: Never\n"
+ " PerOperator:\n"
+ " - Operators: ['&&', '||']\n"
+ " Style: OnePerLine\n"
+ " MinChainLength: 3",
+ &Style)
+ .value());
+ EXPECT_EQ(Style.BreakBinaryOperations.Default, FormatStyle::BBO_Never);
+ ASSERT_EQ(Style.BreakBinaryOperations.PerOperator.size(), 1u);
+ std::vector<tok::TokenKind> ExpectedOps = {tok::ampamp, tok::pipepipe};
+ EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Operators, ExpectedOps);
+ EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Style,
+ FormatStyle::BBO_OnePerLine);
+ EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].MinChainLength, 3u);
+
+ // Parse ">" and ">>" which have edge cases: clang-format splits ">>" into
+ // two ">" tokens, so ">>" maps to tok::greatergreater while ">" maps to
+ // tok::greater.
+ Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
+ EXPECT_EQ(0, parseConfiguration("BreakBinaryOperations:\n"
+ " Default: Never\n"
+ " PerOperator:\n"
+ " - Operators: ['>', '>>']\n"
+ " Style: OnePerLine",
+ &Style)
+ .value());
+ ASSERT_EQ(Style.BreakBinaryOperations.PerOperator.size(), 1u);
+ std::vector<tok::TokenKind> ExpectedShiftOps = {tok::greater,
+ tok::greatergreater};
+ EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Operators,
+ ExpectedShiftOps);
+
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
+ CHECK_PARSE("BreakConstructorInitializers: BeforeComma",
+ BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
+ CHECK_PARSE("BreakConstructorInitializers: AfterColon",
+ BreakConstructorInitializers, FormatStyle::BCIS_AfterColon);
+ CHECK_PARSE("BreakConstructorInitializers: AfterComma",
+ BreakConstructorInitializers, FormatStyle::BCIS_AfterComma);
+ CHECK_PARSE("BreakConstructorInitializers: BeforeColon",
+ BreakConstructorInitializers, FormatStyle::BCIS_BeforeColon);
+ // For backward compatibility:
+ CHECK_PARSE("BreakConstructorInitializersBeforeComma: true",
+ BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
+
+ Style.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
+ CHECK_PARSE("BreakInheritanceList: AfterComma", BreakInheritanceList,
+ FormatStyle::BILS_AfterComma);
+ CHECK_PARSE("BreakInheritanceList: BeforeComma", BreakInheritanceList,
+ FormatStyle::BILS_BeforeComma);
+ CHECK_PARSE("BreakInheritanceList: AfterColon", BreakInheritanceList,
+ FormatStyle::BILS_AfterColon);
+ CHECK_PARSE("BreakInheritanceList: BeforeColon", BreakInheritanceList,
+ FormatStyle::BILS_BeforeColon);
+ // For backward compatibility:
+ CHECK_PARSE("BreakBeforeInheritanceComma: true", BreakInheritanceList,
+ FormatStyle::BILS_BeforeComma);
+
+ Style.BinPackParameters = FormatStyle::BPPS_OnePerLine;
+ CHECK_PARSE("BinPackParameters: BinPack", BinPackParameters,
+ FormatStyle::BPPS_BinPack);
+ CHECK_PARSE("BinPackParameters: OnePerLine", BinPackParameters,
+ FormatStyle::BPPS_OnePerLine);
+ CHECK_PARSE("BinPackParameters: AlwaysOnePerLine", BinPackParameters,
+ FormatStyle::BPPS_AlwaysOnePerLine);
+ // For backward compatibility.
+ CHECK_PARSE("BinPackParameters: true", BinPackParameters,
+ FormatStyle::BPPS_BinPack);
+ CHECK_PARSE("BinPackParameters: false", BinPackParameters,
+ FormatStyle::BPPS_OnePerLine);
+
+ Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
+ CHECK_PARSE("PackConstructorInitializers: Never", PackConstructorInitializers,
+ FormatStyle::PCIS_Never);
+ CHECK_PARSE("PackConstructorInitializers: BinPack",
+ PackConstructorInitializers, FormatStyle::PCIS_BinPack);
+ CHECK_PARSE("PackConstructorInitializers: CurrentLine",
+ PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
+ CHECK_PARSE("PackConstructorInitializers: NextLine",
+ PackConstructorInitializers, FormatStyle::PCIS_NextLine);
+ CHECK_PARSE("PackConstructorInitializers: NextLineOnly",
+ PackConstructorInitializers, FormatStyle::PCIS_NextLineOnly);
+ // For backward compatibility:
+ CHECK_PARSE("BasedOnStyle: Google\n"
+ "ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
+ "AllowAllConstructorInitializersOnNextLine: false",
+ PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
+ Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine;
+ CHECK_PARSE("BasedOnStyle: Google\n"
+ "ConstructorInitializerAllOnOneLineOrOnePerLine: false",
+ PackConstructorInitializers, FormatStyle::PCIS_BinPack);
+ CHECK_PARSE("ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
+ "AllowAllConstructorInitializersOnNextLine: true",
+ PackConstructorInitializers, FormatStyle::PCIS_NextLine);
+ Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
+ CHECK_PARSE("ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
+ "AllowAllConstructorInitializersOnNextLine: false",
+ PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
+
+ Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
+ CHECK_PARSE("EmptyLineBeforeAccessModifier: Never",
+ EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Never);
+ CHECK_PARSE("EmptyLineBeforeAccessModifier: Leave",
+ EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Leave);
+ CHECK_PARSE("EmptyLineBeforeAccessModifier: LogicalBlock",
+ EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_LogicalBlock);
+ CHECK_PARSE("EmptyLineBeforeAccessModifier: Always",
+ EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Always);
+
+ Style.EnumTrailingComma = FormatStyle::ETC_Insert;
+ CHECK_PARSE("EnumTrailingComma: Leave", EnumTrailingComma,
+ FormatStyle::ETC_Leave);
+ CHECK_PARSE("EnumTrailingComma: Insert", EnumTrailingComma,
+ FormatStyle::ETC_Insert);
+ CHECK_PARSE("EnumTrailingComma: Remove", EnumTrailingComma,
+ FormatStyle::ETC_Remove);
+
+ Style.AlignAfterOpenBracket = false;
+ CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, true);
+ CHECK_PARSE("AlignAfterOpenBracket: DontAlign", AlignAfterOpenBracket, false);
+ // For backward compatibility:
+ CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak", AlignAfterOpenBracket,
+ true);
+ CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak\n"
+ "BreakAfterOpenBracketIf: false",
+ BreakAfterOpenBracketIf, false);
+ CHECK_PARSE("BreakAfterOpenBracketLoop: true\n"
+ "AlignAfterOpenBracket: AlwaysBreak",
+ BreakAfterOpenBracketLoop, true);
+ CHECK_PARSE("AlignAfterOpenBracket: false", AlignAfterOpenBracket, false);
+ CHECK_PARSE("AlignAfterOpenBracket: BlockIndent", AlignAfterOpenBracket,
+ true);
+ Style.AlignAfterOpenBracket = false;
+ CHECK_PARSE("AlignAfterOpenBracket: true", AlignAfterOpenBracket, true);
+
+ Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
+ CHECK_PARSE("AlignEscapedNewlines: DontAlign", AlignEscapedNewlines,
+ FormatStyle::ENAS_DontAlign);
+ CHECK_PARSE("AlignEscapedNewlines: Left", AlignEscapedNewlines,
+ FormatStyle::ENAS_Left);
+ CHECK_PARSE("AlignEscapedNewlines: LeftWithLastLine", AlignEscapedNewlines,
+ FormatStyle::ENAS_LeftWithLastLine);
+ CHECK_PARSE("AlignEscapedNewlines: Right", AlignEscapedNewlines,
+ FormatStyle::ENAS_Right);
+ // For backward compatibility:
+ CHECK_PARSE("AlignEscapedNewlinesLeft: true", AlignEscapedNewlines,
+ FormatStyle::ENAS_Left);
+ CHECK_PARSE("AlignEscapedNewlinesLeft: false", AlignEscapedNewlines,
+ FormatStyle::ENAS_Right);
+
+ Style.AlignOperands = FormatStyle::OAS_Align;
+ CHECK_PARSE("AlignOperands: DontAlign", AlignOperands,
+ FormatStyle::OAS_DontAlign);
+ CHECK_PARSE("AlignOperands: Align", AlignOperands, FormatStyle::OAS_Align);
+ CHECK_PARSE("AlignOperands: AlignAfterOperator", AlignOperands,
+ FormatStyle::OAS_AlignAfterOperator);
+ // For backward compatibility:
+ CHECK_PARSE("AlignOperands: false", AlignOperands,
+ FormatStyle::OAS_DontAlign);
+ CHECK_PARSE("AlignOperands: true", AlignOperands, FormatStyle::OAS_Align);
+
+ CHECK_PARSE("AlignTrailingComments: Leave", AlignTrailingComments,
+ FormatStyle::TrailingCommentsAlignmentStyle(
+ {FormatStyle::TCAS_Leave, 0, true}));
+ CHECK_PARSE("AlignTrailingComments: Always", AlignTrailingComments,
+ FormatStyle::TrailingCommentsAlignmentStyle(
+ {FormatStyle::TCAS_Always, 0, true}));
+ CHECK_PARSE("AlignTrailingComments: Never", AlignTrailingComments,
+ FormatStyle::TrailingCommentsAlignmentStyle(
+ {FormatStyle::TCAS_Never, 0, true}));
+ // For backwards compatibility
+ CHECK_PARSE("AlignTrailingComments: true", AlignTrailingComments,
+ FormatStyle::TrailingCommentsAlignmentStyle(
+ {FormatStyle::TCAS_Always, 0, true}));
+ CHECK_PARSE("AlignTrailingComments: false", AlignTrailingComments,
+ FormatStyle::TrailingCommentsAlignmentStyle(
+ {FormatStyle::TCAS_Never, 0, true}));
+ CHECK_PARSE_NESTED_VALUE("Kind: Always", AlignTrailingComments, Kind,
+ FormatStyle::TCAS_Always);
+ CHECK_PARSE_NESTED_VALUE("Kind: Never", AlignTrailingComments, Kind,
+ FormatStyle::TCAS_Never);
+ CHECK_PARSE_NESTED_VALUE("Kind: Leave", AlignTrailingComments, Kind,
+ FormatStyle::TCAS_Leave);
+ CHECK_PARSE_NESTED_VALUE("OverEmptyLines: 1234", AlignTrailingComments,
+ OverEmptyLines, 1234u);
+ CHECK_PARSE_NESTED_BOOL(AlignTrailingComments, AlignPPAndNotPP);
+
+ Style.UseTab = FormatStyle::UT_ForIndentation;
+ CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);
+ CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
+ CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always);
+ CHECK_PARSE("UseTab: ForContinuationAndIndentation", UseTab,
+ FormatStyle::UT_ForContinuationAndIndentation);
+ CHECK_PARSE("UseTab: AlignWithSpaces", UseTab,
+ FormatStyle::UT_AlignWithSpaces);
+ // For backward compatibility:
+ CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never);
+ CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always);
+
+ Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
+ CHECK_PARSE("AllowShortBlocksOnASingleLine: Never",
+ AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never);
+ CHECK_PARSE("AllowShortBlocksOnASingleLine: Empty",
+ AllowShortBlocksOnASingleLine, FormatStyle::SBS_Empty);
+ CHECK_PARSE("AllowShortBlocksOnASingleLine: Always",
+ AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
+ // For backward compatibility:
+ CHECK_PARSE("AllowShortBlocksOnASingleLine: false",
+ AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never);
+ CHECK_PARSE("AllowShortBlocksOnASingleLine: true",
+ AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
+
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle());
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle::setEmptyAndInline());
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: Empty",
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle::setEmptyOnly());
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle::setAll());
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: InlineOnly",
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle::setInlineOnly());
+
+ // For backward compatibility:
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle());
+ CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
+ AllowShortFunctionsOnASingleLine,
+ FormatStyle::ShortFunctionStyle::setAll());
+
+ Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
+ CHECK_PARSE("AllowShortLambdasOnASingleLine: None",
+ AllowShortLambdasOnASingleLine, FormatStyle::SLS_None);
+ CHECK_PARSE("AllowShortLambdasOnASingleLine: Empty",
+ AllowShortLambdasOnASingleLine, FormatStyle::SLS_Empty);
+ CHECK_PARSE("AllowShortLambdasOnASingleLine: Inline",
+ AllowShortLambdasOnASingleLine, FormatStyle::SLS_Inline);
+ CHECK_PARSE("AllowShortLambdasOnASingleLine: All",
+ AllowShortLambdasOnASingleLine, FormatStyle::SLS_All);
+ // For backward compatibility:
+ CHECK_PARSE("AllowShortLambdasOnASingleLine: false",
+ AllowShortLambdasOnASingleLine, FormatStyle::SLS_None);
+ CHECK_PARSE("AllowShortLambdasOnASingleLine: true",
+ AllowShortLambdasOnASingleLine, FormatStyle::SLS_All);
+
+ Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Both;
+ CHECK_PARSE("SpaceAroundPointerQualifiers: Default",
+ SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Default);
+ CHECK_PARSE("SpaceAroundPointerQualifiers: Before",
+ SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Before);
+ CHECK_PARSE("SpaceAroundPointerQualifiers: After",
+ SpaceAroundPointerQualifiers, FormatStyle::SAPQ_After);
+ CHECK_PARSE("SpaceAroundPointerQualifiers: Both",
+ SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Both);
+
+ Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
+ CHECK_PARSE("SpaceBeforeParens: Never", SpaceBeforeParens,
+ FormatStyle::SBPO_Never);
+ CHECK_PARSE("SpaceBeforeParens: Always", SpaceBeforeParens,
+ FormatStyle::SBPO_Always);
+ CHECK_PARSE("SpaceBeforeParens: ControlStatements", SpaceBeforeParens,
+ FormatStyle::SBPO_ControlStatements);
+ CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptControlMacros",
+ SpaceBeforeParens,
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros);
+ CHECK_PARSE("SpaceBeforeParens: NonEmptyParentheses", SpaceBeforeParens,
+ FormatStyle::SBPO_NonEmptyParentheses);
+ CHECK_PARSE("SpaceBeforeParens: Custom", SpaceBeforeParens,
+ FormatStyle::SBPO_Custom);
+ // For backward compatibility:
+ CHECK_PARSE("SpaceAfterControlStatementKeyword: false", SpaceBeforeParens,
+ FormatStyle::SBPO_Never);
+ CHECK_PARSE("SpaceAfterControlStatementKeyword: true", SpaceBeforeParens,
+ FormatStyle::SBPO_ControlStatements);
+ CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptForEachMacros",
+ SpaceBeforeParens,
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros);
+
+ Style.SpaceInEmptyBraces = FormatStyle::SIEB_Never;
+ CHECK_PARSE("SpaceInEmptyBraces: Always", SpaceInEmptyBraces,
+ FormatStyle::SIEB_Always);
+ CHECK_PARSE("SpaceInEmptyBraces: Block", SpaceInEmptyBraces,
+ FormatStyle::SIEB_Block);
+ CHECK_PARSE("SpaceInEmptyBraces: Never", SpaceInEmptyBraces,
+ FormatStyle::SIEB_Never);
+ // For backward compatibility:
+ CHECK_PARSE("SpaceInEmptyBlock: true", SpaceInEmptyBraces,
+ FormatStyle::SIEB_Block);
+
+ // For backward compatibility:
+ Style.SpacesInParens = FormatStyle::SIPO_Never;
+ Style.SpacesInParensOptions = {};
+ CHECK_PARSE("SpacesInParentheses: true", SpacesInParens,
+ FormatStyle::SIPO_Custom);
+ Style.SpacesInParens = FormatStyle::SIPO_Never;
+ Style.SpacesInParensOptions = {};
+ CHECK_PARSE(
+ "SpacesInParentheses: true", SpacesInParensOptions,
+ FormatStyle::SpacesInParensCustom(false, true, false, false, true));
+ Style.SpacesInParens = FormatStyle::SIPO_Never;
+ Style.SpacesInParensOptions = {};
+ CHECK_PARSE(
+ "SpacesInConditionalStatement: true", SpacesInParensOptions,
+ FormatStyle::SpacesInParensCustom(false, true, false, false, false));
+ Style.SpacesInParens = FormatStyle::SIPO_Never;
+ Style.SpacesInParensOptions = {};
+ CHECK_PARSE(
+ "SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
+ FormatStyle::SpacesInParensCustom(false, false, true, false, false));
+ Style.SpacesInParens = FormatStyle::SIPO_Never;
+ Style.SpacesInParensOptions = {};
+ CHECK_PARSE(
+ "SpaceInEmptyParentheses: true", SpacesInParensOptions,
+ FormatStyle::SpacesInParensCustom(false, false, false, true, false));
+ Style.SpacesInParens = FormatStyle::SIPO_Never;
+ Style.SpacesInParensOptions = {};
+
+ Style.ColumnLimit = 123;
+ FormatStyle BaseStyle = getLLVMStyle();
+ CHECK_PARSE("BasedOnStyle: LLVM", ColumnLimit, BaseStyle.ColumnLimit);
+ CHECK_PARSE("BasedOnStyle: LLVM\nColumnLimit: 1234", ColumnLimit, 1234u);
+
+ Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
+ CHECK_PARSE("BreakBeforeBraces: Attach", BreakBeforeBraces,
+ FormatStyle::BS_Attach);
+ CHECK_PARSE("BreakBeforeBraces: Linux", BreakBeforeBraces,
+ FormatStyle::BS_Linux);
+ CHECK_PARSE("BreakBeforeBraces: Mozilla", BreakBeforeBraces,
+ FormatStyle::BS_Mozilla);
+ CHECK_PARSE("BreakBeforeBraces: Stroustrup", BreakBeforeBraces,
+ FormatStyle::BS_Stroustrup);
+ CHECK_PARSE("BreakBeforeBraces: Allman", BreakBeforeBraces,
+ FormatStyle::BS_Allman);
+ CHECK_PARSE("BreakBeforeBraces: Whitesmiths", BreakBeforeBraces,
+ FormatStyle::BS_Whitesmiths);
+ CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU);
+ CHECK_PARSE("BreakBeforeBraces: WebKit", BreakBeforeBraces,
+ FormatStyle::BS_WebKit);
+ CHECK_PARSE("BreakBeforeBraces: Custom", BreakBeforeBraces,
+ FormatStyle::BS_Custom);
+
+ Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Never;
+ CHECK_PARSE("BraceWrapping:\n"
+ " AfterControlStatement: MultiLine",
+ BraceWrapping.AfterControlStatement,
+ FormatStyle::BWACS_MultiLine);
+ CHECK_PARSE("BraceWrapping:\n"
+ " AfterControlStatement: Always",
+ BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Always);
+ CHECK_PARSE("BraceWrapping:\n"
+ " AfterControlStatement: Never",
+ BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never);
+ // For backward compatibility:
+ CHECK_PARSE("BraceWrapping:\n"
+ " AfterControlStatement: true",
+ BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Always);
+ CHECK_PARSE("BraceWrapping:\n"
+ " AfterControlStatement: false",
+ BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never);
+
+ Style.BreakAfterReturnType = FormatStyle::RTBS_All;
+ CHECK_PARSE("BreakAfterReturnType: None", BreakAfterReturnType,
+ FormatStyle::RTBS_None);
+ CHECK_PARSE("BreakAfterReturnType: Automatic", BreakAfterReturnType,
+ FormatStyle::RTBS_Automatic);
+ CHECK_PARSE("BreakAfterReturnType: ExceptShortType", BreakAfterReturnType,
+ FormatStyle::RTBS_ExceptShortType);
+ CHECK_PARSE("BreakAfterReturnType: All", BreakAfterReturnType,
+ FormatStyle::RTBS_All);
+ CHECK_PARSE("BreakAfterReturnType: TopLevel", BreakAfterReturnType,
+ FormatStyle::RTBS_TopLevel);
+ CHECK_PARSE("BreakAfterReturnType: AllDefinitions", BreakAfterReturnType,
+ FormatStyle::RTBS_AllDefinitions);
+ CHECK_PARSE("BreakAfterReturnType: TopLevelDefinitions", BreakAfterReturnType,
+ FormatStyle::RTBS_TopLevelDefinitions);
+ // For backward compatibility:
+ CHECK_PARSE("AlwaysBreakAfterReturnType: None", BreakAfterReturnType,
+ FormatStyle::RTBS_None);
+ CHECK_PARSE("AlwaysBreakAfterReturnType: Automatic", BreakAfterReturnType,
+ FormatStyle::RTBS_Automatic);
+ CHECK_PARSE("AlwaysBreakAfterReturnType: ExceptShortType",
+ BreakAfterReturnType, FormatStyle::RTBS_ExceptShortType);
+ CHECK_PARSE("AlwaysBreakAfterReturnType: All", BreakAfterReturnType,
+ FormatStyle::RTBS_All);
+ CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevel", BreakAfterReturnType,
+ FormatStyle::RTBS_TopLevel);
+ CHECK_PARSE("AlwaysBreakAfterReturnType: AllDefinitions",
+ BreakAfterReturnType, FormatStyle::RTBS_AllDefinitions);
+ CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevelDefinitions",
+ BreakAfterReturnType, FormatStyle::RTBS_TopLevelDefinitions);
+
+ Style.BreakTemplateDeclarations = FormatStyle::BTDS_Yes;
+ CHECK_PARSE("BreakTemplateDeclarations: Leave", BreakTemplateDeclarations,
+ FormatStyle::BTDS_Leave);
+ CHECK_PARSE("BreakTemplateDeclarations: No", BreakTemplateDeclarations,
+ FormatStyle::BTDS_No);
+ CHECK_PARSE("BreakTemplateDeclarations: MultiLine", BreakTemplateDeclarations,
+ FormatStyle::BTDS_MultiLine);
+ CHECK_PARSE("BreakTemplateDeclarations: Yes", BreakTemplateDeclarations,
+ FormatStyle::BTDS_Yes);
+ CHECK_PARSE("BreakTemplateDeclarations: false", BreakTemplateDeclarations,
+ FormatStyle::BTDS_MultiLine);
+ CHECK_PARSE("BreakTemplateDeclarations: true", BreakTemplateDeclarations,
+ FormatStyle::BTDS_Yes);
+ // For backward compatibility:
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: Leave",
+ BreakTemplateDeclarations, FormatStyle::BTDS_Leave);
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: No", BreakTemplateDeclarations,
+ FormatStyle::BTDS_No);
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: MultiLine",
+ BreakTemplateDeclarations, FormatStyle::BTDS_MultiLine);
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: Yes", BreakTemplateDeclarations,
+ FormatStyle::BTDS_Yes);
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: false",
+ BreakTemplateDeclarations, FormatStyle::BTDS_MultiLine);
+ CHECK_PARSE("AlwaysBreakTemplateDeclarations: true",
+ BreakTemplateDeclarations, FormatStyle::BTDS_Yes);
+
+ Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
+ CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None",
+ AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_None);
+ CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: All",
+ AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_All);
+ CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: TopLevel",
+ AlwaysBreakAfterDefinitionReturnType,
+ FormatStyle::DRTBS_TopLevel);
+
+ Style.NamespaceIndentation = FormatStyle::NI_All;
+ CHECK_PARSE("NamespaceIndentation: None", NamespaceIndentation,
+ FormatStyle::NI_None);
+ CHECK_PARSE("NamespaceIndentation: Inner", NamespaceIndentation,
+ FormatStyle::NI_Inner);
+ CHECK_PARSE("NamespaceIndentation: All", NamespaceIndentation,
+ FormatStyle::NI_All);
+
+ Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_OnlyFirstIf;
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Never",
+ AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never);
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: WithoutElse",
+ AllowShortIfStatementsOnASingleLine,
+ FormatStyle::SIS_WithoutElse);
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: OnlyFirstIf",
+ AllowShortIfStatementsOnASingleLine,
+ FormatStyle::SIS_OnlyFirstIf);
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: AllIfsAndElse",
+ AllowShortIfStatementsOnASingleLine,
+ FormatStyle::SIS_AllIfsAndElse);
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Always",
+ AllowShortIfStatementsOnASingleLine,
+ FormatStyle::SIS_OnlyFirstIf);
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: false",
+ AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never);
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
+ AllowShortIfStatementsOnASingleLine,
+ FormatStyle::SIS_WithoutElse);
+
+ Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+ CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock,
+ FormatStyle::IEBS_AfterExternBlock);
+ CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock,
+ FormatStyle::IEBS_Indent);
+ CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock,
+ FormatStyle::IEBS_NoIndent);
+ CHECK_PARSE("IndentExternBlock: true", IndentExternBlock,
+ FormatStyle::IEBS_Indent);
+ CHECK_PARSE("IndentExternBlock: false", IndentExternBlock,
+ FormatStyle::IEBS_NoIndent);
+
+ Style.IndentGotoLabels = FormatStyle::IGLS_OuterIndent;
+ CHECK_PARSE("IndentGotoLabels: NoIndent", IndentGotoLabels,
+ FormatStyle::IGLS_NoIndent);
+ CHECK_PARSE("IndentGotoLabels: OuterIndent", IndentGotoLabels,
+ FormatStyle::IGLS_OuterIndent);
+ CHECK_PARSE("IndentGotoLabels: InnerIndent", IndentGotoLabels,
+ FormatStyle::IGLS_InnerIndent);
+ CHECK_PARSE("IndentGotoLabels: HalfIndent", IndentGotoLabels,
+ FormatStyle::IGLS_HalfIndent);
+ CHECK_PARSE("IndentGotoLabels: false", IndentGotoLabels,
+ FormatStyle::IGLS_NoIndent);
+ CHECK_PARSE("IndentGotoLabels: true", IndentGotoLabels,
+ FormatStyle::IGLS_OuterIndent);
+
+ Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
+ CHECK_PARSE("BitFieldColonSpacing: Both", BitFieldColonSpacing,
+ FormatStyle::BFCS_Both);
+ CHECK_PARSE("BitFieldColonSpacing: None", BitFieldColonSpacing,
+ FormatStyle::BFCS_None);
+ CHECK_PARSE("BitFieldColonSpacing: Before", BitFieldColonSpacing,
+ FormatStyle::BFCS_Before);
+ CHECK_PARSE("BitFieldColonSpacing: After", BitFieldColonSpacing,
+ FormatStyle::BFCS_After);
+
+ Style.SortJavaStaticImport = FormatStyle::SJSIO_Before;
+ CHECK_PARSE("SortJavaStaticImport: After", SortJavaStaticImport,
+ FormatStyle::SJSIO_After);
+ CHECK_PARSE("SortJavaStaticImport: Before", SortJavaStaticImport,
+ FormatStyle::SJSIO_Before);
+
+ Style.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric;
+ CHECK_PARSE("SortUsingDeclarations: Never", SortUsingDeclarations,
+ FormatStyle::SUD_Never);
+ CHECK_PARSE("SortUsingDeclarations: Lexicographic", SortUsingDeclarations,
+ FormatStyle::SUD_Lexicographic);
+ CHECK_PARSE("SortUsingDeclarations: LexicographicNumeric",
+ SortUsingDeclarations, FormatStyle::SUD_LexicographicNumeric);
+ // For backward compatibility:
+ CHECK_PARSE("SortUsingDeclarations: false", SortUsingDeclarations,
+ FormatStyle::SUD_Never);
+ CHECK_PARSE("SortUsingDeclarations: true", SortUsingDeclarations,
+ FormatStyle::SUD_LexicographicNumeric);
+
+ CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Never",
+ WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Never);
+ CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Always",
+ WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Always);
+ CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Leave",
+ WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Leave);
+
+ // FIXME: This is required because parsing a configuration simply overwrites
+ // the first N elements of the list instead of resetting it.
+ Style.ForEachMacros.clear();
+ std::vector<std::string> BoostForeach;
+ BoostForeach.push_back("BOOST_FOREACH");
+ CHECK_PARSE("ForEachMacros: [BOOST_FOREACH]", ForEachMacros, BoostForeach);
+ std::vector<std::string> BoostAndQForeach;
+ BoostAndQForeach.push_back("BOOST_FOREACH");
+ BoostAndQForeach.push_back("Q_FOREACH");
+ CHECK_PARSE("ForEachMacros: [BOOST_FOREACH, Q_FOREACH]", ForEachMacros,
+ BoostAndQForeach);
+
+ Style.IfMacros.clear();
+ std::vector<std::string> CustomIfs;
+ CustomIfs.push_back("MYIF");
+ CHECK_PARSE("IfMacros: [MYIF]", IfMacros, CustomIfs);
+
+ Style.AttributeMacros.clear();
+ CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros,
+ std::vector<std::string>{"__capability"});
+ CHECK_PARSE(
+ "BasedOnStyle: Google", AttributeMacros,
+ std::vector<std::string>({"__capability", "absl_nonnull", "absl_nullable",
+ "absl_nullability_unknown"}));
+ Style.AttributeMacros.clear();
+ CHECK_PARSE("AttributeMacros: [attr1, attr2]", AttributeMacros,
+ std::vector<std::string>({"attr1", "attr2"}));
+
+ Style.StatementAttributeLikeMacros.clear();
+ CHECK_PARSE("StatementAttributeLikeMacros: [emit,Q_EMIT]",
+ StatementAttributeLikeMacros,
+ std::vector<std::string>({"emit", "Q_EMIT"}));
+
+ Style.Macros.clear();
+ CHECK_PARSE("{Macros: [foo]}", Macros, std::vector<std::string>({"foo"}));
+ std::vector<std::string> GoogleMacros;
+ GoogleMacros.push_back("ASSIGN_OR_RETURN(a, b)=a = (b)");
+ GoogleMacros.push_back("ASSIGN_OR_RETURN(a, b, c)=a = (b); if (x) return c");
+ CHECK_PARSE("BasedOnStyle: Google", Macros, GoogleMacros);
+
+ Style.StatementMacros.clear();
+ CHECK_PARSE("StatementMacros: [QUNUSED]", StatementMacros,
+ std::vector<std::string>{"QUNUSED"});
+ CHECK_PARSE("StatementMacros: [QUNUSED, QT_REQUIRE_VERSION]", StatementMacros,
+ std::vector<std::string>({"QUNUSED", "QT_REQUIRE_VERSION"}));
+
+ CHECK_PARSE_LIST(JavaImportGroups);
+ CHECK_PARSE_LIST(MacrosSkippedByRemoveParentheses);
+ CHECK_PARSE_LIST(NamespaceMacros);
+ CHECK_PARSE_LIST(ObjCPropertyAttributeOrder);
+ CHECK_PARSE_LIST(TableGenBreakingDAGArgOperators);
+ CHECK_PARSE_LIST(TemplateNames);
+ CHECK_PARSE_LIST(TypeNames);
+ CHECK_PARSE_LIST(TypenameMacros);
+ CHECK_PARSE_LIST(VariableTemplates);
+
+ Style.WhitespaceSensitiveMacros.clear();
+ CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE]",
+ WhitespaceSensitiveMacros, std::vector<std::string>{"STRINGIZE"});
+ CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE, ASSERT]",
+ WhitespaceSensitiveMacros,
+ std::vector<std::string>({"STRINGIZE", "ASSERT"}));
+ Style.WhitespaceSensitiveMacros.clear();
+ CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE']",
+ WhitespaceSensitiveMacros, std::vector<std::string>{"STRINGIZE"});
+ CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE', 'ASSERT']",
+ WhitespaceSensitiveMacros,
+ std::vector<std::string>({"STRINGIZE", "ASSERT"}));
+
+ Style.IncludeStyle.IncludeCategories.clear();
+ std::vector<tooling::IncludeStyle::IncludeCategory> ExpectedCategories = {
+ {"abc/.*", 2, 0, false}, {".*", 1, 0, true}};
+ CHECK_PARSE("IncludeCategories:\n"
+ " - Regex: abc/.*\n"
+ " Priority: 2\n"
+ " - Regex: .*\n"
+ " Priority: 1\n"
+ " CaseSensitive: true",
+ IncludeStyle.IncludeCategories, ExpectedCategories);
+ CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeStyle.IncludeIsMainRegex,
+ "abc$");
+ CHECK_PARSE("IncludeIsMainSourceRegex: 'abc$'",
+ IncludeStyle.IncludeIsMainSourceRegex, "abc$");
+
+ Style.SortIncludes = {};
+ CHECK_PARSE(
+ "SortIncludes: true", SortIncludes,
+ FormatStyle::SortIncludesOptions(
+ {/*Enabled=*/true, /*IgnoreCase=*/false, /*IgnoreExtension=*/false}));
+ CHECK_PARSE("SortIncludes: false", SortIncludes,
+ FormatStyle::SortIncludesOptions({}));
+ CHECK_PARSE(
+ "SortIncludes: CaseInsensitive", SortIncludes,
+ FormatStyle::SortIncludesOptions(
+ {/*Enabled=*/true, /*IgnoreCase=*/true, /*IgnoreExtension=*/false}));
+ CHECK_PARSE(
+ "SortIncludes: CaseSensitive", SortIncludes,
+ FormatStyle::SortIncludesOptions(
+ {/*Enabled=*/true, /*IgnoreCase=*/false, /*IgnoreExtension=*/false}));
+ CHECK_PARSE("SortIncludes: Never", SortIncludes,
+ FormatStyle::SortIncludesOptions({}));
+
+ Style.RawStringFormats.clear();
+ std::vector<FormatStyle::RawStringFormat> ExpectedRawStringFormats = {
+ {
+ FormatStyle::LK_TextProto,
+ {"pb", "proto"},
+ {"PARSE_TEXT_PROTO"},
+ /*CanonicalDelimiter=*/"",
+ "llvm",
+ },
+ {
+ FormatStyle::LK_Cpp,
+ {"cc", "cpp"},
+ {"C_CODEBLOCK", "CPPEVAL"},
+ /*CanonicalDelimiter=*/"cc",
+ /*BasedOnStyle=*/"",
+ },
};
- FormatStyle AlwaysStyle = getLLVMStyle();
- AlwaysStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-
- FormatStyle NeverStyle = getLLVMStyle();
- NeverStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
-
- auto TestKit = MakeUntouchTest("/* FOOBAR */\n"
- "#ifdef FOO\n\n",
- "\n#elifndef BAR\n\n", "\n#endif\n\n", false);
- verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
- verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
-
- TestKit = MakeUntouchTest("/* FOOBAR */\n"
- "#ifdef FOO\n",
- "#elifndef BAR\n", "#endif\n", false);
- verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
- verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
-
- TestKit = MakeUntouchTest("namespace Ns {\n\n",
- "\n} // namespace Ns\n\n"
- "namespace {\n\n",
- "\n} // namespace\n", true);
- verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
- verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
-
- TestKit = MakeUntouchTest("namespace Ns {\n",
- "} // namespace Ns\n\n"
- "namespace {\n",
- "} // namespace\n", true);
- verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
- verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
+ CHECK_PARSE("RawStringFormats:\n"
+ " - Language: TextProto\n"
+ " Delimiters:\n"
+ " - 'pb'\n"
+ " - 'proto'\n"
+ " EnclosingFunctions:\n"
+ " - 'PARSE_TEXT_PROTO'\n"
+ " BasedOnStyle: llvm\n"
+ " - Language: Cpp\n"
+ " Delimiters:\n"
+ " - 'cc'\n"
+ " - 'cpp'\n"
+ " EnclosingFunctions:\n"
+ " - 'C_CODEBLOCK'\n"
+ " - 'CPPEVAL'\n"
+ " CanonicalDelimiter: 'cc'",
+ RawStringFormats, ExpectedRawStringFormats);
+
+ CHECK_PARSE("SpacesInLineCommentPrefix:\n"
+ " Minimum: 0\n"
+ " Maximum: 0",
+ SpacesInLineCommentPrefix.Minimum, 0u);
+ EXPECT_EQ(Style.SpacesInLineCommentPrefix.Maximum, 0u);
+ Style.SpacesInLineCommentPrefix.Minimum = 1;
+ CHECK_PARSE("SpacesInLineCommentPrefix:\n"
+ " Minimum: 2",
+ SpacesInLineCommentPrefix.Minimum, 0u);
+ CHECK_PARSE("SpacesInLineCommentPrefix:\n"
+ " Maximum: -1",
+ SpacesInLineCommentPrefix.Maximum, -1u);
+ CHECK_PARSE("SpacesInLineCommentPrefix:\n"
+ " Minimum: 2",
+ SpacesInLineCommentPrefix.Minimum, 2u);
+ CHECK_PARSE("SpacesInLineCommentPrefix:\n"
+ " Maximum: 1",
+ SpacesInLineCommentPrefix.Maximum, 1u);
+ EXPECT_EQ(Style.SpacesInLineCommentPrefix.Minimum, 1u);
+
+ Style.SpacesInAngles = FormatStyle::SIAS_Always;
+ CHECK_PARSE("SpacesInAngles: Never", SpacesInAngles, FormatStyle::SIAS_Never);
+ CHECK_PARSE("SpacesInAngles: Always", SpacesInAngles,
+ FormatStyle::SIAS_Always);
+ CHECK_PARSE("SpacesInAngles: Leave", SpacesInAngles, FormatStyle::SIAS_Leave);
+ // For backward compatibility:
+ CHECK_PARSE("SpacesInAngles: false", SpacesInAngles, FormatStyle::SIAS_Never);
+ CHECK_PARSE("SpacesInAngles: true", SpacesInAngles, FormatStyle::SIAS_Always);
+
+ CHECK_PARSE("RequiresClausePosition: WithPreceding", RequiresClausePosition,
+ FormatStyle::RCPS_WithPreceding);
+ CHECK_PARSE("RequiresClausePosition: WithFollowing", RequiresClausePosition,
+ FormatStyle::RCPS_WithFollowing);
+ CHECK_PARSE("RequiresClausePosition: SingleLine", RequiresClausePosition,
+ FormatStyle::RCPS_SingleLine);
+ CHECK_PARSE("RequiresClausePosition: OwnLine", RequiresClausePosition,
+ FormatStyle::RCPS_OwnLine);
+
+ CHECK_PARSE("BreakBeforeConceptDeclarations: Never",
+ BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Never);
+ CHECK_PARSE("BreakBeforeConceptDeclarations: Always",
+ BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Always);
+ CHECK_PARSE("BreakBeforeConceptDeclarations: Allowed",
+ BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Allowed);
+ // For backward compatibility:
+ CHECK_PARSE("BreakBeforeConceptDeclarations: true",
+ BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Always);
+ CHECK_PARSE("BreakBeforeConceptDeclarations: false",
+ BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Allowed);
+
+ CHECK_PARSE("BreakAfterAttributes: Always", BreakAfterAttributes,
+ FormatStyle::ABS_Always);
+ CHECK_PARSE("BreakAfterAttributes: Leave", BreakAfterAttributes,
+ FormatStyle::ABS_Leave);
+ CHECK_PARSE("BreakAfterAttributes: Never", BreakAfterAttributes,
+ FormatStyle::ABS_Never);
+
+ const auto DefaultLineEnding = FormatStyle::LE_DeriveLF;
+ CHECK_PARSE("LineEnding: LF", LineEnding, FormatStyle::LE_LF);
+ CHECK_PARSE("LineEnding: CRLF", LineEnding, FormatStyle::LE_CRLF);
+ CHECK_PARSE("LineEnding: DeriveCRLF", LineEnding, FormatStyle::LE_DeriveCRLF);
+ CHECK_PARSE("LineEnding: DeriveLF", LineEnding, DefaultLineEnding);
+ // For backward compatibility:
+ CHECK_PARSE("DeriveLineEnding: false", LineEnding, FormatStyle::LE_LF);
+ Style.LineEnding = DefaultLineEnding;
+ CHECK_PARSE("DeriveLineEnding: false\n"
+ "UseCRLF: true",
+ LineEnding, FormatStyle::LE_CRLF);
+ Style.LineEnding = DefaultLineEnding;
+ CHECK_PARSE("UseCRLF: true", LineEnding, FormatStyle::LE_DeriveCRLF);
+
+ CHECK_PARSE("RemoveParentheses: MultipleParentheses", RemoveParentheses,
+ FormatStyle::RPS_MultipleParentheses);
+ CHECK_PARSE("RemoveParentheses: ReturnStatement", RemoveParentheses,
+ FormatStyle::RPS_ReturnStatement);
+ CHECK_PARSE("RemoveParentheses: Leave", RemoveParentheses,
+ FormatStyle::RPS_Leave);
+
+ CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: Always",
+ AllowBreakBeforeNoexceptSpecifier, FormatStyle::BBNSS_Always);
+ CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: OnlyWithParen",
+ AllowBreakBeforeNoexceptSpecifier,
+ FormatStyle::BBNSS_OnlyWithParen);
+ CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: Never",
+ AllowBreakBeforeNoexceptSpecifier, FormatStyle::BBNSS_Never);
+
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
+ CHECK_PARSE("SeparateDefinitionBlocks: Always", SeparateDefinitionBlocks,
+ FormatStyle::SDS_Always);
+ CHECK_PARSE("SeparateDefinitionBlocks: Leave", SeparateDefinitionBlocks,
+ FormatStyle::SDS_Leave);
+ CHECK_PARSE("SeparateDefinitionBlocks: Never", SeparateDefinitionBlocks,
+ FormatStyle::SDS_Never);
+
+ CHECK_PARSE("Cpp11BracedListStyle: Block", Cpp11BracedListStyle,
+ FormatStyle::BLS_Block);
+ CHECK_PARSE("Cpp11BracedListStyle: FunctionCall", Cpp11BracedListStyle,
+ FormatStyle::BLS_FunctionCall);
+ CHECK_PARSE("Cpp11BracedListStyle: AlignFirstComment", Cpp11BracedListStyle,
+ FormatStyle::BLS_AlignFirstComment);
+ // For backward compatibility:
+ CHECK_PARSE("Cpp11BracedListStyle: false", Cpp11BracedListStyle,
+ FormatStyle::BLS_Block);
+ CHECK_PARSE("Cpp11BracedListStyle: true", Cpp11BracedListStyle,
+ FormatStyle::BLS_AlignFirstComment);
+
+ constexpr FormatStyle::IntegerLiteralSeparatorStyle
+ ExpectedIntegerLiteralSeparatorStyle{/*Binary=*/2,
+ /*BinaryMinDigitInsert=*/5,
+ /*BinaryMaxDigitRemove=*/2,
+ /*Decimal=*/6,
+ /*DecimalMinDigitInsert=*/6,
+ /*DecimalMaxDigitRemove=*/3,
+ /*Hex=*/4,
+ /*HexMinDigitInsert=*/2,
+ /*HexMaxDigitRemove=*/1};
+ CHECK_PARSE("IntegerLiteralSeparator:\n"
+ " Binary: 2\n"
+ " BinaryMinDigitsInsert: 5\n"
+ " BinaryMaxDigitsRemove: 2\n"
+ " Decimal: 6\n"
+ " DecimalMinDigitsInsert: 6\n"
+ " DecimalMaxDigitsRemove: 3\n"
+ " Hex: 4\n"
+ " HexMinDigitsInsert: 2\n"
+ " HexMaxDigitsRemove: 1",
+ IntegerLiteralSeparator, ExpectedIntegerLiteralSeparatorStyle);
+
+ // Backward compatibility:
+ CHECK_PARSE_NESTED_VALUE("BinaryMinDigits: 6", IntegerLiteralSeparator,
+ BinaryMinDigitsInsert, 6);
+ CHECK_PARSE_NESTED_VALUE("DecimalMinDigits: 5", IntegerLiteralSeparator,
+ DecimalMinDigitsInsert, 5);
+ CHECK_PARSE_NESTED_VALUE("HexMinDigits: 5", IntegerLiteralSeparator,
+ HexMinDigitsInsert, 5);
}
-TEST_F(DefinitionBlockSeparatorTest, Always) {
- FormatStyle Style = getLLVMStyle();
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
-
- verifyFormat("// clang-format off\n"
- "template<class T>\n"
- "concept C = not A<S<T>>;\n"
- "// clang-format on\n"
- "\n"
- "struct E {};",
- Style);
-
- std::string Prefix = "namespace {\n";
- std::string Infix = "\n"
- "// Enum test1\n"
- "// Enum test2\n"
- "enum Foo { FOO, BAR };\n"
- "\n"
- "/*\n"
- "test1\n"
- "test2\n"
- "*/\n"
- "/*const*/ int foo(int i, int j) {\n"
- " int r = i + j;\n"
- " return r;\n"
- "}\n"
- "\n"
- "// Foobar\n"
- "int i, j, k;\n"
- "\n"
- "// Comment for function\n"
- "// Comment line 2\n"
- "// Comment line 3\n"
- "int bar(int j, int k) {\n"
- " {\n"
- " int r = j * k;\n"
- " return r;\n"
- " }\n"
- "}\n"
- "\n"
- "int bar2(int j, int k) {\n"
- " int r = j / k;\n"
- " return r;\n"
- "}\n"
- "\n"
- "/* Comment block in one line*/\n"
- "enum Bar { FOOBAR, BARFOO };\n"
- "\n"
- "int bar3(int j, int k, const enum Bar b) {\n"
- " // A comment\n"
- " int r = j % k;\n"
- " if (struct S = getS()) {\n"
- " // if condition\n"
- " }\n"
- " return r;\n"
- "}\n";
- std::string Postfix = "\n"
- "} // namespace\n"
- "\n"
- "namespace T {\n"
- "int i, j, k;\n"
- "} // namespace T";
- verifyFormat(Prefix + removeEmptyLines(Infix) + removeEmptyLines(Postfix),
- Style, Prefix + Infix + Postfix);
+TEST(ConfigParseTest, ParsesConfigurationWithLanguages) {
+ FormatStyle Style = {};
+ Style.Language = FormatStyle::LK_Cpp;
+ CHECK_PARSE("Language: Cpp\n"
+ "IndentWidth: 12",
+ IndentWidth, 12u);
+ EXPECT_EQ(parseConfiguration("Language: JavaScript\n"
+ "IndentWidth: 34",
+ &Style),
+ ParseError::Unsuitable);
+ FormatStyle BinPackedTCS = {};
+ BinPackedTCS.Language = FormatStyle::LK_JavaScript;
+ EXPECT_EQ(parseConfiguration("BinPackArguments: true\n"
+ "InsertTrailingCommas: Wrapped",
+ &BinPackedTCS),
+ ParseError::BinPackTrailingCommaConflict);
+ EXPECT_EQ(12u, Style.IndentWidth);
+ CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
+ EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
+
+ Style.Language = FormatStyle::LK_JavaScript;
+ CHECK_PARSE("Language: JavaScript\n"
+ "IndentWidth: 12",
+ IndentWidth, 12u);
+ CHECK_PARSE("IndentWidth: 23", IndentWidth, 23u);
+ EXPECT_EQ(parseConfiguration("Language: Cpp\n"
+ "IndentWidth: 34",
+ &Style),
+ ParseError::Unsuitable);
+ EXPECT_EQ(23u, Style.IndentWidth);
+ CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
+ EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
+
+ CHECK_PARSE("BasedOnStyle: LLVM\n"
+ "IndentWidth: 67",
+ IndentWidth, 67u);
+
+ CHECK_PARSE("---\n"
+ "Language: JavaScript\n"
+ "IndentWidth: 12\n"
+ "---\n"
+ "Language: Cpp\n"
+ "IndentWidth: 34\n"
+ "...\n",
+ IndentWidth, 12u);
+
+ Style.Language = FormatStyle::LK_Cpp;
+ CHECK_PARSE("---\n"
+ "Language: JavaScript\n"
+ "IndentWidth: 12\n"
+ "---\n"
+ "Language: Cpp\n"
+ "IndentWidth: 34\n"
+ "...\n",
+ IndentWidth, 34u);
+ CHECK_PARSE("---\n"
+ "IndentWidth: 78\n"
+ "---\n"
+ "Language: JavaScript\n"
+ "IndentWidth: 56\n"
+ "...\n",
+ IndentWidth, 78u);
+
+ Style.ColumnLimit = 123;
+ Style.IndentWidth = 234;
+ Style.BreakBeforeBraces = FormatStyle::BS_Linux;
+ Style.TabWidth = 345;
+ EXPECT_FALSE(parseConfiguration("---\n"
+ "IndentWidth: 456\n"
+ "BreakBeforeBraces: Allman\n"
+ "---\n"
+ "Language: JavaScript\n"
+ "IndentWidth: 111\n"
+ "TabWidth: 111\n"
+ "---\n"
+ "Language: Cpp\n"
+ "BreakBeforeBraces: Stroustrup\n"
+ "TabWidth: 789\n"
+ "...\n",
+ &Style));
+ EXPECT_EQ(123u, Style.ColumnLimit);
+ EXPECT_EQ(456u, Style.IndentWidth);
+ EXPECT_EQ(FormatStyle::BS_Stroustrup, Style.BreakBeforeBraces);
+ EXPECT_EQ(789u, Style.TabWidth);
+
+ EXPECT_EQ(parseConfiguration("---\n"
+ "Language: JavaScript\n"
+ "IndentWidth: 56\n"
+ "---\n"
+ "IndentWidth: 78\n"
+ "...\n",
+ &Style),
+ ParseError::Error);
+ EXPECT_EQ(parseConfiguration("---\n"
+ "Language: JavaScript\n"
+ "IndentWidth: 56\n"
+ "---\n"
+ "Language: JavaScript\n"
+ "IndentWidth: 78\n"
+ "...\n",
+ &Style),
+ ParseError::Error);
+
+ EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
+
+ Style.Language = FormatStyle::LK_Verilog;
+ CHECK_PARSE("---\n"
+ "Language: Verilog\n"
+ "IndentWidth: 12\n"
+ "---\n"
+ "Language: Cpp\n"
+ "IndentWidth: 34\n"
+ "...\n",
+ IndentWidth, 12u);
+ CHECK_PARSE("---\n"
+ "IndentWidth: 78\n"
+ "---\n"
+ "Language: Verilog\n"
+ "IndentWidth: 56\n"
+ "...\n",
+ IndentWidth, 56u);
}
-TEST_F(DefinitionBlockSeparatorTest, Never) {
- FormatStyle Style = getLLVMStyle();
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
- std::string Prefix = "namespace {\n";
- std::string Postfix = "// Enum test1\n"
- "// Enum test2\n"
- "enum Foo { FOO, BAR };\n"
- "\n"
- "/*\n"
- "test1\n"
- "test2\n"
- "*/\n"
- "/*const*/ int foo(int i, int j) {\n"
- " int r = i + j;\n"
- " return r;\n"
- "}\n"
- "\n"
- "// Foobar\n"
- "int i, j, k;\n"
- "\n"
- "// Comment for function\n"
- "// Comment line 2\n"
- "// Comment line 3\n"
- "int bar(int j, int k) {\n"
- " {\n"
- " int r = j * k;\n"
- " return r;\n"
- " }\n"
- "}\n"
- "\n"
- "int bar2(int j, int k) {\n"
- " int r = j / k;\n"
- " return r;\n"
- "}\n"
- "\n"
- "/* Comment block in one line*/\n"
- "enum Bar { FOOBAR, BARFOO };\n"
- "\n"
- "int bar3(int j, int k, const enum Bar b) {\n"
- " // A comment\n"
- " int r = j % k;\n"
- " if (struct S = getS()) {\n"
- " // if condition\n"
- " }\n"
- " return r;\n"
- "}\n"
- "} // namespace";
- verifyFormat(Prefix + "\n\n\n" + Postfix, Style,
- Prefix + removeEmptyLines(Postfix));
+TEST(ConfigParseTest, AllowCommentOnlyConfigFile) {
+ FormatStyle Style = {};
+ Style.Language = FormatStyle::LK_Cpp;
+ EXPECT_EQ(parseConfiguration("#Language: C", &Style), ParseError::Success);
+ EXPECT_EQ(Style.Language, FormatStyle::LK_Cpp);
}
-TEST_F(DefinitionBlockSeparatorTest, OpeningBracketOwnsLine) {
- FormatStyle Style = getLLVMStyle();
- Style.BreakBeforeBraces = FormatStyle::BS_Allman;
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
- verifyFormat("namespace NS\n"
- "{\n"
- "// Enum test1\n"
- "// Enum test2\n"
- "enum Foo\n"
- "{\n"
- " FOO,\n"
- " BAR\n"
- "};\n"
- "\n"
- "/*\n"
- "test1\n"
- "test2\n"
- "*/\n"
- "/*const*/ int foo(int i, int j)\n"
- "{\n"
- " int r = i + j;\n"
- " return r;\n"
- "}\n"
- "\n"
- "// Foobar\n"
- "int i, j, k;\n"
- "\n"
- "// Comment for function\n"
- "// Comment line 2\n"
- "// Comment line 3\n"
- "int bar(int j, int k)\n"
- "{\n"
- " {\n"
- " int r = j * k;\n"
- " return r;\n"
- " }\n"
- "}\n"
- "\n"
- "int bar2(int j, int k)\n"
- "{\n"
- " int r = j / k;\n"
- " return r;\n"
- "}\n"
- "\n"
- "enum Bar\n"
- "{\n"
- " FOOBAR,\n"
- " BARFOO\n"
- "};\n"
- "\n"
- "int bar3(int j, int k, const enum Bar b)\n"
- "{\n"
- " // A comment\n"
- " int r = j % k;\n"
- " if (struct S = getS())\n"
- " {\n"
- " // if condition\n"
- " }\n"
- " return r;\n"
- "}\n"
- "} // namespace NS",
- Style);
+TEST(ConfigParseTest, AllowCppForC) {
+ FormatStyle Style = {};
+ Style.Language = FormatStyle::LK_C;
+ EXPECT_EQ(parseConfiguration("Language: Cpp", &Style), ParseError::Success);
+
+ CHECK_PARSE("---\n"
+ "IndentWidth: 4\n"
+ "---\n"
+ "Language: Cpp\n"
+ "IndentWidth: 8\n",
+ IndentWidth, 8u);
+
+ EXPECT_EQ(parseConfiguration("---\n"
+ "Language: ObjC\n"
+ "---\n"
+ "Language: Cpp\n",
+ &Style),
+ ParseError::Success);
}
-TEST_F(DefinitionBlockSeparatorTest, TryBlocks) {
- FormatStyle Style = getLLVMStyle();
- Style.BreakBeforeBraces = FormatStyle::BS_Allman;
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
- verifyFormat("void FunctionWithInternalTry()\n"
- "{\n"
- " try\n"
- " {\n"
- " return;\n"
- " }\n"
- " catch (const std::exception &)\n"
- " {\n"
- " }\n"
- "}",
- Style, "", /*Inverse=*/false);
- verifyFormat("void FunctionWithTryBlock()\n"
- "try\n"
- "{\n"
- " return;\n"
- "}\n"
- "catch (const std::exception &)\n"
- "{\n"
- "}",
- Style, "", /*Inverse=*/false);
+TEST(ConfigParseTest, HandleDotHFile) {
+ FormatStyle Style = {};
+ Style.Language = FormatStyle::LK_Cpp;
+ EXPECT_EQ(parseConfiguration("Language: C", &Style,
+ /*AllowUnknownOptions=*/false,
+ /*IsDotHFile=*/true),
+ ParseError::Success);
+ EXPECT_EQ(Style.Language, FormatStyle::LK_C);
+
+ Style = {};
+ Style.Language = FormatStyle::LK_Cpp;
+ EXPECT_EQ(parseConfiguration("Language: Cpp\n"
+ "...\n"
+ "Language: C",
+ &Style,
+ /*AllowUnknownOptions=*/false,
+ /*IsDotHFile=*/true),
+ ParseError::Success);
+ EXPECT_EQ(Style.Language, FormatStyle::LK_Cpp);
}
-TEST_F(DefinitionBlockSeparatorTest, Leave) {
+TEST(ConfigParseTest, UsesLanguageForBasedOnStyle) {
+ FormatStyle Style = {};
+ Style.Language = FormatStyle::LK_JavaScript;
+ Style.BreakBeforeTernaryOperators = true;
+ EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Style).value());
+ EXPECT_FALSE(Style.BreakBeforeTernaryOperators);
+
+ Style.BreakBeforeTernaryOperators = true;
+ EXPECT_EQ(0, parseConfiguration("---\n"
+ "BasedOnStyle: Google\n"
+ "---\n"
+ "Language: JavaScript\n"
+ "IndentWidth: 76\n"
+ "...\n",
+ &Style)
+ .value());
+ EXPECT_FALSE(Style.BreakBeforeTernaryOperators);
+ EXPECT_EQ(76u, Style.IndentWidth);
+ EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
+}
+
+TEST(ConfigParseTest, ConfigurationRoundTripTest) {
FormatStyle Style = getLLVMStyle();
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Leave;
- Style.MaxEmptyLinesToKeep = 3;
- std::string LeaveAs = "namespace {\n"
- "\n"
- "// Enum test1\n"
- "// Enum test2\n"
- "enum Foo { FOO, BAR };\n"
- "\n\n\n"
- "/*\n"
- "test1\n"
- "test2\n"
- "*/\n"
- "/*const*/ int foo(int i, int j) {\n"
- " int r = i + j;\n"
- " return r;\n"
- "}\n"
- "\n"
- "// Foobar\n"
- "int i, j, k;\n"
- "\n"
- "// Comment for function\n"
- "// Comment line 2\n"
- "// Comment line 3\n"
- "int bar(int j, int k) {\n"
- " {\n"
- " int r = j * k;\n"
- " return r;\n"
- " }\n"
- "}\n"
- "\n"
- "int bar2(int j, int k) {\n"
- " int r = j / k;\n"
- " return r;\n"
- "}\n"
- "\n"
- "// Comment for inline enum\n"
- "enum Bar { FOOBAR, BARFOO };\n"
- "int bar3(int j, int k, const enum Bar b) {\n"
- " // A comment\n"
- " int r = j % k;\n"
- " if (struct S = getS()) {\n"
- " // if condition\n"
- " }\n"
- " return r;\n"
- "}\n"
- "} // namespace";
- verifyFormat(LeaveAs, Style, LeaveAs);
+ std::string YAML = configurationAsText(Style);
+ FormatStyle ParsedStyle = {};
+ ParsedStyle.Language = FormatStyle::LK_Cpp;
+ EXPECT_EQ(0, parseConfiguration(YAML, &ParsedStyle).value());
+ EXPECT_EQ(Style, ParsedStyle);
}
-TEST_F(DefinitionBlockSeparatorTest, CSharp) {
- FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
- Style.AllowShortEnumsOnASingleLine = false;
- verifyFormat("namespace {\r\n"
- "public class SomeTinyClass {\r\n"
- " int X;\r\n"
- "}\r\n"
- "\r\n"
- "public class AnotherTinyClass {\r\n"
- " int Y;\r\n"
- "}\r\n"
- "\r\n"
- "internal static String toString() {\r\n"
- "}\r\n"
- "\r\n"
- "// Comment for enum\r\n"
- "public enum var {\r\n"
- " none,\r\n"
- " @string,\r\n"
- " bool,\r\n"
- " @enum\r\n"
- "}\r\n"
- "\r\n"
- "// Test\r\n"
- "[STAThread]\r\n"
- "static void Main(string[] args) {\r\n"
- " Console.WriteLine(\"HelloWorld\");\r\n"
- "}\r\n"
- "\r\n"
- "static decimal Test() {\r\n"
- "}\r\n"
- "}\r\n"
- "\r\n"
- "public class FoobarClass {\r\n"
- " int foobar;\r\n"
- "}\r\n"
- "\r\n"
- "public class LogFactory<TLogger>\r\n"
- " where TLogger : class, new() {\r\n"
- " int i;\r\n"
- "}",
- Style);
+TEST(ConfigParseTest, GetStyleWithEmptyFileName) {
+ llvm::vfs::InMemoryFileSystem FS;
+ auto Style1 = getStyle("file", "", "Google", "", &FS);
+ ASSERT_TRUE((bool)Style1);
+ ASSERT_EQ(*Style1, getGoogleStyle());
}
-TEST_F(DefinitionBlockSeparatorTest, JavaScript) {
- FormatStyle Style = getLLVMStyle(FormatStyle::LK_JavaScript);
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
- Style.AllowShortEnumsOnASingleLine = false;
- verifyFormat("export const enum Foo {\n"
- " A = 1,\n"
- " B\n"
- "}\n"
- "\n"
- "export function A() {\n"
- "}\n"
- "\n"
- "export default function B() {\n"
- "}\n"
- "\n"
- "export function C() {\n"
- "}\n"
- "\n"
- "var t, p, q;\n"
- "\n"
- "export abstract class X {\n"
- " y: number;\n"
- "}\n"
- "\n"
- "export const enum Bar {\n"
- " D = 1,\n"
- " E\n"
- "}",
- Style);
+TEST(ConfigParseTest, GetStyleOfFile) {
+ llvm::vfs::InMemoryFileSystem FS;
+ // Test 1: format file in the same directory.
+ ASSERT_TRUE(
+ FS.addFile("/a/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
+ ASSERT_TRUE(
+ FS.addFile("/a/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
+ auto Style1 = getStyle("file", "/a/.clang-format", "Google", "", &FS);
+ ASSERT_TRUE((bool)Style1);
+ ASSERT_EQ(*Style1, getLLVMStyle());
+
+ // Test 2.1: fallback to default.
+ ASSERT_TRUE(
+ FS.addFile("/b/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
+ auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", "", &FS);
+ ASSERT_TRUE((bool)Style2);
+ ASSERT_EQ(*Style2, getMozillaStyle());
+
+ // Test 2.2: no format on 'none' fallback style.
+ Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS);
+ ASSERT_TRUE((bool)Style2);
+ ASSERT_EQ(*Style2, getNoStyle());
+
+ // Test 2.3: format if config is found with no based style while fallback is
+ // 'none'.
+ ASSERT_TRUE(FS.addFile("/b/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("IndentWidth: 2")));
+ Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS);
+ ASSERT_TRUE((bool)Style2);
+ ASSERT_EQ(*Style2, getLLVMStyle());
+
+ // Test 2.4: format if yaml with no based style, while fallback is 'none'.
+ Style2 = getStyle("{}", "a.h", "none", "", &FS);
+ ASSERT_TRUE((bool)Style2);
+ ASSERT_EQ(*Style2, getLLVMStyle());
+
+ // Test 3: format file in parent directory.
+ ASSERT_TRUE(
+ FS.addFile("/c/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+ ASSERT_TRUE(FS.addFile("/c/sub/sub/sub/test.cpp", 0,
+ llvm::MemoryBuffer::getMemBuffer("int i;")));
+ auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+ ASSERT_TRUE((bool)Style3);
+ ASSERT_EQ(*Style3, getGoogleStyle());
+
+ // Test 4: error on invalid fallback style
+ auto Style4 = getStyle("file", "a.h", "KungFu", "", &FS);
+ ASSERT_FALSE((bool)Style4);
+ llvm::consumeError(Style4.takeError());
+
+ // Test 5: error on invalid yaml on command line
+ auto Style5 = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
+ /*AllowUnknownOptions=*/false, dropDiagnosticHandler);
+ ASSERT_FALSE((bool)Style5);
+ llvm::consumeError(Style5.takeError());
+
+ // Test 6: error on invalid style
+ auto Style6 = getStyle("KungFu", "a.h", "LLVM", "", &FS);
+ ASSERT_FALSE((bool)Style6);
+ llvm::consumeError(Style6.takeError());
+
+ // Test 7: found config file, error on parsing it
+ ASSERT_TRUE(
+ FS.addFile("/d/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM\n"
+ "InvalidKey: InvalidValue")));
+ ASSERT_TRUE(
+ FS.addFile("/d/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
+ auto Style7a = getStyle("file", "/d/.clang-format", "LLVM", "", &FS,
+ /*AllowUnknownOptions=*/false, dropDiagnosticHandler);
+ ASSERT_FALSE((bool)Style7a);
+ llvm::consumeError(Style7a.takeError());
+
+ auto Style7b = getStyle("file", "/d/.clang-format", "LLVM", "", &FS,
+ /*AllowUnknownOptions=*/true, dropDiagnosticHandler);
+ ASSERT_TRUE((bool)Style7b);
+
+ // Test 8: inferred per-language defaults apply.
+ auto StyleTd = getStyle("file", "x.td", "llvm", "", &FS);
+ ASSERT_TRUE((bool)StyleTd);
+ ASSERT_EQ(*StyleTd, getLLVMStyle(FormatStyle::LK_TableGen));
+
+ // Test 9.1.1: overwriting a file style, when no parent file exists with no
+ // fallback style.
+ ASSERT_TRUE(FS.addFile(
+ "/e/sub/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: InheritParentConfig\n"
+ "ColumnLimit: 20")));
+ ASSERT_TRUE(FS.addFile("/e/sub/code.cpp", 0,
+ llvm::MemoryBuffer::getMemBuffer("int i;")));
+ auto Style9 = getStyle("file", "/e/sub/code.cpp", "none", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, [] {
+ auto Style = getNoStyle();
+ Style.ColumnLimit = 20;
+ return Style;
+ }());
+
+ // Test 9.1.2: propagate more than one level with no parent file.
+ ASSERT_TRUE(FS.addFile("/e/sub/sub/code.cpp", 0,
+ llvm::MemoryBuffer::getMemBuffer("int i;")));
+ ASSERT_TRUE(FS.addFile("/e/sub/sub/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer(
+ "BasedOnStyle: InheritParentConfig\n"
+ "WhitespaceSensitiveMacros: ['FOO', 'BAR']")));
+ std::vector<std::string> NonDefaultWhiteSpaceMacros =
+ Style9->WhitespaceSensitiveMacros;
+ NonDefaultWhiteSpaceMacros[0] = "FOO";
+ NonDefaultWhiteSpaceMacros[1] = "BAR";
+
+ ASSERT_NE(Style9->WhitespaceSensitiveMacros, NonDefaultWhiteSpaceMacros);
+ Style9 = getStyle("file", "/e/sub/sub/code.cpp", "none", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, [&NonDefaultWhiteSpaceMacros] {
+ auto Style = getNoStyle();
+ Style.ColumnLimit = 20;
+ Style.WhitespaceSensitiveMacros = NonDefaultWhiteSpaceMacros;
+ return Style;
+ }());
+
+ // Test 9.2: with LLVM fallback style
+ Style9 = getStyle("file", "/e/sub/code.cpp", "LLVM", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, [] {
+ auto Style = getLLVMStyle();
+ Style.ColumnLimit = 20;
+ return Style;
+ }());
+
+ // Test 9.3: with a parent file
+ ASSERT_TRUE(
+ FS.addFile("/e/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google\n"
+ "UseTab: Always")));
+ Style9 = getStyle("file", "/e/sub/code.cpp", "none", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, [] {
+ auto Style = getGoogleStyle();
+ Style.ColumnLimit = 20;
+ Style.UseTab = FormatStyle::UT_Always;
+ return Style;
+ }());
+
+ // Test 9.4: propagate more than one level with a parent file.
+ const auto SubSubStyle = [&NonDefaultWhiteSpaceMacros] {
+ auto Style = getGoogleStyle();
+ Style.ColumnLimit = 20;
+ Style.UseTab = FormatStyle::UT_Always;
+ Style.WhitespaceSensitiveMacros = NonDefaultWhiteSpaceMacros;
+ return Style;
+ }();
+
+ ASSERT_NE(Style9->WhitespaceSensitiveMacros, NonDefaultWhiteSpaceMacros);
+ Style9 = getStyle("file", "/e/sub/sub/code.cpp", "none", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, SubSubStyle);
+
+ // Test 9.5: use InheritParentConfig as style name
+ Style9 =
+ getStyle("inheritparentconfig", "/e/sub/sub/code.cpp", "none", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, SubSubStyle);
+
+ // Test 9.6: use command line style with inheritance
+ Style9 = getStyle("{BasedOnStyle: InheritParentConfig}",
+ "/e/sub/sub/code.cpp", "none", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, SubSubStyle);
+
+ // Test 9.7: use command line style with inheritance and own config
+ Style9 = getStyle("{BasedOnStyle: InheritParentConfig, "
+ "WhitespaceSensitiveMacros: ['FOO', 'BAR']}",
+ "/e/sub/code.cpp", "none", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, SubSubStyle);
+
+ // Test 9.8: use inheritance from a file without BasedOnStyle
+ ASSERT_TRUE(FS.addFile(
+ "/e/withoutbase/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BracedInitializerIndentWidth: 2\n"
+ "ColumnLimit: 123")));
+ ASSERT_TRUE(
+ FS.addFile("/e/withoutbase/sub/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer(
+ "BasedOnStyle: InheritParentConfig\nIndentWidth: 7")));
+ // Make sure we do not use the fallback style
+ Style9 = getStyle("file", "/e/withoutbase/code.cpp", "google", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, [] {
+ auto Style = getLLVMStyle();
+ Style.BracedInitializerIndentWidth = 2;
+ Style.ColumnLimit = 123;
+ return Style;
+ }());
+
+ Style9 = getStyle("file", "/e/withoutbase/sub/code.cpp", "google", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, [] {
+ auto Style = getLLVMStyle();
+ Style.BracedInitializerIndentWidth = 2;
+ Style.ColumnLimit = 123;
+ Style.IndentWidth = 7;
+ return Style;
+ }());
+
+ // Test 9.9: use inheritance from a specific config file.
+ Style9 = getStyle("file:/e/sub/sub/.clang-format", "/e/sub/sub/code.cpp",
+ "none", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style9));
+ ASSERT_EQ(*Style9, SubSubStyle);
+}
+
+TEST(ConfigParseTest, GetStyleOfSpecificFile) {
+ llvm::vfs::InMemoryFileSystem FS;
+ // Specify absolute path to a format file in a parent directory.
+ ASSERT_TRUE(
+ FS.addFile("/e/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
+ ASSERT_TRUE(
+ FS.addFile("/e/explicit.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+ ASSERT_TRUE(FS.addFile("/e/sub/sub/sub/test.cpp", 0,
+ llvm::MemoryBuffer::getMemBuffer("int i;")));
+ auto Style = getStyle("file:/e/explicit.clang-format",
+ "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style));
+ ASSERT_EQ(*Style, getGoogleStyle());
+
+ // Specify relative path to a format file.
+ ASSERT_TRUE(
+ FS.addFile("../../e/explicit.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+ Style = getStyle("file:../../e/explicit.clang-format",
+ "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style));
+ ASSERT_EQ(*Style, getGoogleStyle());
+
+ // Specify path to a format file that does not exist.
+ Style = getStyle("file:/e/missing.clang-format", "/e/sub/sub/sub/test.cpp",
+ "LLVM", "", &FS);
+ ASSERT_FALSE(static_cast<bool>(Style));
+ llvm::consumeError(Style.takeError());
+
+ // Specify path to a file on the filesystem.
+ SmallString<128> FormatFilePath;
+ std::error_code ECF = llvm::sys::fs::createTemporaryFile(
+ "FormatFileTest", "tpl", FormatFilePath);
+ EXPECT_FALSE((bool)ECF);
+ llvm::raw_fd_ostream FormatFileTest(FormatFilePath, ECF);
+ EXPECT_FALSE((bool)ECF);
+ FormatFileTest << "BasedOnStyle: Google\n";
+ FormatFileTest.close();
+
+ SmallString<128> TestFilePath;
+ std::error_code ECT =
+ llvm::sys::fs::createTemporaryFile("CodeFileTest", "cc", TestFilePath);
+ EXPECT_FALSE((bool)ECT);
+ llvm::raw_fd_ostream CodeFileTest(TestFilePath, ECT);
+ CodeFileTest << "int i;\n";
+ CodeFileTest.close();
+
+ std::string format_file_arg = std::string("file:") + FormatFilePath.c_str();
+ Style = getStyle(format_file_arg, TestFilePath, "LLVM", "", nullptr);
+
+ llvm::sys::fs::remove(FormatFilePath.c_str());
+ llvm::sys::fs::remove(TestFilePath.c_str());
+ ASSERT_TRUE(static_cast<bool>(Style));
+ ASSERT_EQ(*Style, getGoogleStyle());
+}
+
+TEST(ConfigParseTest, GetStyleOutput) {
+ llvm::vfs::InMemoryFileSystem FS;
+
+ // Don't suppress output.
+ testing::internal::CaptureStderr();
+ auto Style = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
+ /*AllowUnknownOptions=*/true);
+ auto Output = testing::internal::GetCapturedStderr();
+ ASSERT_TRUE((bool)Style);
+ ASSERT_FALSE(Output.empty());
+
+ // Suppress stderr.
+ testing::internal::CaptureStderr();
+ Style = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
+ /*AllowUnknownOptions=*/true, dropDiagnosticHandler);
+ Output = testing::internal::GetCapturedStderr();
+ ASSERT_TRUE((bool)Style);
+ ASSERT_TRUE(Output.empty());
+}
+
+TEST(ConfigParseTest, RedirectInheritance) {
+ llvm::vfs::InMemoryFileSystem FS;
+ constexpr StringRef Config("BasedOnStyle: InheritParentConfig\n"
+ "ColumnLimit: 20");
+ constexpr StringRef Code("int *f(int i, int j);");
+
+ ASSERT_TRUE(
+ FS.addFile("/a/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: GNU")));
+ ASSERT_TRUE(FS.addFile("/a/proj/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer(
+ "BasedOnStyle: InheritParentConfig=/a/config")));
+ ASSERT_TRUE(
+ FS.addFile("/a/proj/test.cc", 0, llvm::MemoryBuffer::getMemBuffer(Code)));
+ auto Style = getStyle("file", "/a/proj/test.cc", "none", "", &FS);
+ ASSERT_FALSE(static_cast<bool>(Style));
+ ASSERT_EQ(toString(Style.takeError()),
+ "Failed to inherit configuration directory /a/config");
+
+ ASSERT_TRUE(FS.addFile("/a/config/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer(Config)));
+ Style = getStyle("file", "/a/proj/test.cc", "none", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style));
+ ASSERT_EQ(*Style, [] {
+ auto Style = getGNUStyle();
+ Style.ColumnLimit = 20;
+ return Style;
+ }());
+
+ ASSERT_TRUE(FS.addFile(
+ "/a/proj/src/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: InheritParentConfig\n"
+ "PointerAlignment: Left")));
+ ASSERT_TRUE(FS.addFile("/a/proj/src/test.cc", 0,
+ llvm::MemoryBuffer::getMemBuffer(Code)));
+ Style = getStyle("file", "/a/proj/src/test.cc", "none", "", &FS);
+ ASSERT_TRUE(static_cast<bool>(Style));
+ ASSERT_EQ(*Style, [] {
+ auto Style = getGNUStyle();
+ Style.ColumnLimit = 20;
+ Style.PointerAlignment = FormatStyle::PAS_Left;
+ return Style;
+ }());
+
+ ASSERT_TRUE(FS.addFile("/a/loop/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer(
+ "BasedOnStyle: InheritParentConfig=config/")));
+ ASSERT_TRUE(
+ FS.addFile("/a/loop/test.cc", 0, llvm::MemoryBuffer::getMemBuffer(Code)));
+ ASSERT_TRUE(FS.addFile("/a/loop/config/_clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer(Config)));
+ Style = getStyle("file", "/a/loop/test.cc", "none", "", &FS);
+ ASSERT_FALSE(static_cast<bool>(Style));
+ ASSERT_EQ(toString(Style.takeError()),
+ "Loop detected when inheriting configuration file in /a/loop");
}
+
} // namespace
} // namespace format
} // namespace clang
>From 53e8bb940d8430763e56695a2aedcaee99216cd3 Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:09:17 -0700
Subject: [PATCH 16/17] Update print statement from 'Hello' to 'Goodbye'
---
.../Format/DefinitionBlockSeparatorTest.cpp | 2372 ++++-------------
1 file changed, 577 insertions(+), 1795 deletions(-)
diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
index 8cd0dd840acf8..b1b4b1d047523 100644
--- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
+++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
@@ -1,4 +1,4 @@
-//===- unittest/Format/ConfigParseTest.cpp - Config parsing unit tests ----===//
+//===- DefinitionBlockSeparatorTest.cpp - Formatting unit tests -----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,1832 +6,614 @@
//
//===----------------------------------------------------------------------===//
+#include "FormatTestUtils.h"
#include "clang/Format/Format.h"
-#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/Support/Debug.h"
#include "gtest/gtest.h"
+#define DEBUG_TYPE "definition-block-separator-test"
+
namespace clang {
namespace format {
namespace {
-void dropDiagnosticHandler(const llvm::SMDiagnostic &, void *) {}
-FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); }
-
-#define EXPECT_ALL_STYLES_EQUAL(Styles) \
- for (size_t i = 1; i < Styles.size(); ++i) \
- EXPECT_EQ(Styles[0], Styles[i]) \
- << "Style #" << i << " of " << Styles.size() << " differs from Style #0"
-
-TEST(ConfigParseTest, GetsPredefinedStyleByName) {
- SmallVector<FormatStyle, 3> Styles;
- Styles.resize(3);
-
- Styles[0] = getLLVMStyle();
- EXPECT_TRUE(getPredefinedStyle("LLVM", FormatStyle::LK_Cpp, &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("lLvM", FormatStyle::LK_Cpp, &Styles[2]));
- EXPECT_ALL_STYLES_EQUAL(Styles);
-
- Styles[0] = getGoogleStyle();
- EXPECT_TRUE(getPredefinedStyle("Google", FormatStyle::LK_Cpp, &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("gOOgle", FormatStyle::LK_Cpp, &Styles[2]));
- EXPECT_ALL_STYLES_EQUAL(Styles);
-
- Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript);
- EXPECT_TRUE(
- getPredefinedStyle("Google", FormatStyle::LK_JavaScript, &Styles[1]));
- EXPECT_TRUE(
- getPredefinedStyle("gOOgle", FormatStyle::LK_JavaScript, &Styles[2]));
- EXPECT_ALL_STYLES_EQUAL(Styles);
-
- Styles[0] = getChromiumStyle(FormatStyle::LK_Cpp);
- EXPECT_TRUE(getPredefinedStyle("Chromium", FormatStyle::LK_Cpp, &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("cHRoMiUM", FormatStyle::LK_Cpp, &Styles[2]));
- EXPECT_ALL_STYLES_EQUAL(Styles);
-
- Styles[0] = getMozillaStyle();
- EXPECT_TRUE(getPredefinedStyle("Mozilla", FormatStyle::LK_Cpp, &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("moZILla", FormatStyle::LK_Cpp, &Styles[2]));
- EXPECT_ALL_STYLES_EQUAL(Styles);
-
- Styles[0] = getWebKitStyle();
- EXPECT_TRUE(getPredefinedStyle("WebKit", FormatStyle::LK_Cpp, &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("wEbKit", FormatStyle::LK_Cpp, &Styles[2]));
- EXPECT_ALL_STYLES_EQUAL(Styles);
-
- Styles[0] = getGNUStyle();
- EXPECT_TRUE(getPredefinedStyle("GNU", FormatStyle::LK_Cpp, &Styles[1]));
- EXPECT_TRUE(getPredefinedStyle("gnU", FormatStyle::LK_Cpp, &Styles[2]));
- EXPECT_ALL_STYLES_EQUAL(Styles);
-
- Styles[0] = getClangFormatStyle();
- EXPECT_TRUE(
- getPredefinedStyle("clang-format", FormatStyle::LK_Cpp, &Styles[1]));
- EXPECT_TRUE(
- getPredefinedStyle("Clang-format", FormatStyle::LK_Cpp, &Styles[2]));
- EXPECT_ALL_STYLES_EQUAL(Styles);
-
- EXPECT_FALSE(getPredefinedStyle("qwerty", FormatStyle::LK_Cpp, &Styles[0]));
-}
-
-TEST(ConfigParseTest, GetsCorrectBasedOnStyle) {
- SmallVector<FormatStyle, 8> Styles;
- Styles.resize(2);
-
- Styles[0] = getGoogleStyle();
- Styles[1] = getLLVMStyle();
- EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
- EXPECT_ALL_STYLES_EQUAL(Styles);
-
- Styles.resize(5);
- Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript);
- Styles[1] = getLLVMStyle();
- Styles[1].Language = FormatStyle::LK_JavaScript;
- EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
-
- Styles[2] = getLLVMStyle();
- Styles[2].Language = FormatStyle::LK_JavaScript;
- EXPECT_EQ(0, parseConfiguration("Language: JavaScript\n"
- "BasedOnStyle: Google",
- &Styles[2])
- .value());
-
- Styles[3] = getLLVMStyle();
- Styles[3].Language = FormatStyle::LK_JavaScript;
- EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google\n"
- "Language: JavaScript",
- &Styles[3])
- .value());
-
- Styles[4] = getLLVMStyle();
- Styles[4].Language = FormatStyle::LK_JavaScript;
- EXPECT_EQ(0, parseConfiguration("---\n"
- "BasedOnStyle: LLVM\n"
- "IndentWidth: 123\n"
- "---\n"
- "BasedOnStyle: Google\n"
- "Language: JavaScript",
- &Styles[4])
- .value());
- EXPECT_ALL_STYLES_EQUAL(Styles);
+class DefinitionBlockSeparatorTest : public testing::Test {
+protected:
+ static std::string
+ separateDefinitionBlocks(StringRef Code,
+ const std::vector<tooling::Range> &Ranges,
+ const FormatStyle &Style = getLLVMStyle()) {
+ LLVM_DEBUG(llvm::errs() << "---\n");
+ LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+ tooling::Replacements Replaces = reformat(Style, Code, Ranges, "<stdin>");
+ auto Result = applyAllReplacements(Code, Replaces);
+ EXPECT_TRUE(static_cast<bool>(Result));
+ LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+ return *Result;
+ }
+
+ static std::string
+ separateDefinitionBlocks(StringRef Code,
+ const FormatStyle &Style = getLLVMStyle()) {
+ return separateDefinitionBlocks(
+ Code,
+ /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
+ }
+
+ static void _verifyFormat(const char *File, int Line, StringRef Code,
+ const FormatStyle &Style = getLLVMStyle(),
+ StringRef ExpectedCode = "", bool Inverse = true) {
+ testing::ScopedTrace t(File, Line, testing::Message() << Code.str());
+ bool HasOriginalCode = true;
+ if (ExpectedCode == "") {
+ ExpectedCode = Code;
+ HasOriginalCode = false;
+ }
+
+ EXPECT_EQ(ExpectedCode, separateDefinitionBlocks(ExpectedCode, Style))
+ << "Expected code is not stable";
+ if (Inverse) {
+ FormatStyle InverseStyle = Style;
+ if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always)
+ InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
+ else
+ InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+ EXPECT_NE(ExpectedCode,
+ separateDefinitionBlocks(ExpectedCode, InverseStyle))
+ << "Inverse formatting makes no difference";
+ }
+ std::string CodeToFormat =
+ HasOriginalCode ? Code.str() : removeEmptyLines(Code);
+ std::string Result = separateDefinitionBlocks(CodeToFormat, Style);
+ EXPECT_EQ(ExpectedCode, Result) << "Test failed. Formatted:\n" << Result;
+ }
+
+ static std::string removeEmptyLines(StringRef Code) {
+ std::string Result = "";
+ for (auto Char : Code.str()) {
+ if (Result.size()) {
+ auto LastChar = Result.back();
+ if ((Char == '\n' && LastChar == '\n') ||
+ (Char == '\r' && (LastChar == '\r' || LastChar == '\n'))) {
+ continue;
+ }
+ }
+ Result.push_back(Char);
+ }
+ return Result;
+ }
+};
+
+#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)
+
+TEST_F(DefinitionBlockSeparatorTest, Basic) {
+ FormatStyle Style = getLLVMStyle();
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+ verifyFormat("int foo(int i, int j) {\n"
+ " int r = i + j;\n"
+ " return r;\n"
+ "}\n"
+ "\n"
+ "int bar(int j, int k) {\n"
+ " int r = j + k;\n"
+ " return r;\n"
+ "}",
+ Style);
+
+ verifyFormat("struct foo {\n"
+ " int i, j;\n"
+ "};\n"
+ "\n"
+ "struct bar {\n"
+ " int j, k;\n"
+ "};",
+ Style);
+
+ verifyFormat("union foo {\n"
+ " int i, j;\n"
+ "};\n"
+ "\n"
+ "union bar {\n"
+ " int j, k;\n"
+ "};",
+ Style);
+
+ verifyFormat("class foo {\n"
+ " int i, j;\n"
+ "};\n"
+ "\n"
+ "class bar {\n"
+ " int j, k;\n"
+ "};",
+ Style);
+
+ verifyFormat("namespace foo {\n"
+ "int i, j;\n"
+ "}\n"
+ "\n"
+ "namespace bar {\n"
+ "int j, k;\n"
+ "}",
+ Style);
+
+ verifyFormat("enum Foo { FOO, BAR };\n"
+ "\n"
+ "enum Bar { FOOBAR, BARFOO };",
+ Style);
+
+ FormatStyle BreakAfterReturnTypeStyle = Style;
+ BreakAfterReturnTypeStyle.BreakAfterReturnType = FormatStyle::RTBS_All;
+ // Test uppercased long typename
+ verifyFormat("class Foo {\n"
+ " void\n"
+ " Bar(int t, int p) {\n"
+ " int r = t + p;\n"
+ " return r;\n"
+ " }\n"
+ "\n"
+ " HRESULT\n"
+ " Foobar(int t, int p) {\n"
+ " int r = t * p;\n"
+ " return r;\n"
+ " }\n"
+ "}",
+ BreakAfterReturnTypeStyle);
}
-#define CHECK_PARSE_BOOL_FIELD(FIELD, CONFIG_NAME) \
- Style.FIELD = false; \
- EXPECT_EQ(0, parseConfiguration(CONFIG_NAME ": true", &Style).value()); \
- EXPECT_TRUE(Style.FIELD); \
- EXPECT_EQ(0, parseConfiguration(CONFIG_NAME ": false", &Style).value()); \
- EXPECT_FALSE(Style.FIELD)
-
-#define CHECK_PARSE_BOOL(FIELD) CHECK_PARSE_BOOL_FIELD(FIELD, #FIELD)
-
-#define CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, CONFIG_NAME) \
- Style.STRUCT.FIELD = false; \
- EXPECT_EQ(0, \
- parseConfiguration(#STRUCT ":\n " CONFIG_NAME ": true", &Style) \
- .value()); \
- EXPECT_TRUE(Style.STRUCT.FIELD); \
- EXPECT_EQ(0, \
- parseConfiguration(#STRUCT ":\n " CONFIG_NAME ": false", &Style) \
- .value()); \
- EXPECT_FALSE(Style.STRUCT.FIELD)
-
-#define CHECK_PARSE_NESTED_BOOL(STRUCT, FIELD) \
- CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, #FIELD)
-
-#define CHECK_PARSE(TEXT, FIELD, VALUE) \
- EXPECT_NE(VALUE, Style.FIELD) << "Initial value already the same!"; \
- EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value()); \
- EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"
-
-#define CHECK_PARSE_INT(FIELD) CHECK_PARSE(#FIELD ": -1234", FIELD, -1234)
-
-#define CHECK_PARSE_UNSIGNED(FIELD) CHECK_PARSE(#FIELD ": 1234", FIELD, 1234u)
-
-#define CHECK_PARSE_LIST(FIELD) \
- CHECK_PARSE(#FIELD ": [foo]", FIELD, std::vector<std::string>{"foo"})
-
-#define CHECK_PARSE_NESTED_VALUE(TEXT, STRUCT, FIELD, VALUE) \
- EXPECT_NE(VALUE, Style.STRUCT.FIELD) << "Initial value already the same!"; \
- EXPECT_EQ(0, parseConfiguration(#STRUCT ":\n " TEXT, &Style).value()); \
- EXPECT_EQ(VALUE, Style.STRUCT.FIELD) << "Unexpected value after parsing!"
-
-TEST(ConfigParseTest, ParsesConfigurationBools) {
- FormatStyle Style = {};
- Style.Language = FormatStyle::LK_Cpp;
- CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine);
- CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
- CHECK_PARSE_BOOL(AllowBreakBeforeQtProperty);
- CHECK_PARSE_BOOL(AllowShortCaseExpressionOnASingleLine);
- CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);
- CHECK_PARSE_BOOL(AllowShortCompoundRequirementOnASingleLine);
- CHECK_PARSE_BOOL(AllowShortEnumsOnASingleLine);
- CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
- CHECK_PARSE_BOOL(AllowShortNamespacesOnASingleLine);
- CHECK_PARSE_BOOL(BinPackArguments);
- CHECK_PARSE_BOOL(BinPackLongBracedList);
- CHECK_PARSE_BOOL(BreakAdjacentStringLiterals);
- CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations);
- CHECK_PARSE_BOOL(BreakAfterOpenBracketBracedList);
- CHECK_PARSE_BOOL(BreakAfterOpenBracketFunction);
- CHECK_PARSE_BOOL(BreakAfterOpenBracketIf);
- CHECK_PARSE_BOOL(BreakAfterOpenBracketLoop);
- CHECK_PARSE_BOOL(BreakAfterOpenBracketSwitch);
- CHECK_PARSE_BOOL(BreakBeforeCloseBracketBracedList);
- CHECK_PARSE_BOOL(BreakBeforeCloseBracketFunction);
- CHECK_PARSE_BOOL(BreakBeforeCloseBracketIf);
- CHECK_PARSE_BOOL(BreakBeforeCloseBracketLoop);
- CHECK_PARSE_BOOL(BreakBeforeCloseBracketSwitch);
- CHECK_PARSE_BOOL(BreakBeforeTemplateCloser);
- CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
- CHECK_PARSE_BOOL(BreakStringLiterals);
- CHECK_PARSE_BOOL(CompactNamespaces);
- CHECK_PARSE_BOOL(DerivePointerAlignment);
- CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding");
- CHECK_PARSE_BOOL(DisableFormat);
- CHECK_PARSE_BOOL(IndentAccessModifiers);
- CHECK_PARSE_BOOL(IndentCaseBlocks);
- CHECK_PARSE_BOOL(IndentCaseLabels);
- CHECK_PARSE_BOOL(IndentExportBlock);
- CHECK_PARSE_BOOL(IndentRequiresClause);
- CHECK_PARSE_BOOL_FIELD(IndentRequiresClause, "IndentRequires");
- CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
- CHECK_PARSE_BOOL(InsertBraces);
- CHECK_PARSE_BOOL(InsertNewlineAtEOF);
- CHECK_PARSE_BOOL_FIELD(KeepEmptyLines.AtEndOfFile, "KeepEmptyLinesAtEOF");
- CHECK_PARSE_BOOL_FIELD(KeepEmptyLines.AtStartOfBlock,
- "KeepEmptyLinesAtTheStartOfBlocks");
- CHECK_PARSE_BOOL(KeepFormFeed);
- CHECK_PARSE_BOOL(ObjCSpaceAfterMethodDeclarationPrefix);
- CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
- CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
- CHECK_PARSE_BOOL(RemoveBracesLLVM);
- CHECK_PARSE_BOOL(RemoveEmptyLinesInUnwrappedLines);
- CHECK_PARSE_BOOL(RemoveSemicolon);
- CHECK_PARSE_BOOL(SkipMacroDefinitionBody);
- CHECK_PARSE_BOOL(SpacesInSquareBrackets);
- CHECK_PARSE_BOOL(SpacesInContainerLiterals);
- CHECK_PARSE_BOOL(SpaceAfterCStyleCast);
- CHECK_PARSE_BOOL(SpaceAfterTemplateKeyword);
- CHECK_PARSE_BOOL(SpaceAfterOperatorKeyword);
- CHECK_PARSE_BOOL(SpaceAfterLogicalNot);
- CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators);
- CHECK_PARSE_BOOL(SpaceBeforeCaseColon);
- CHECK_PARSE_BOOL(SpaceBeforeCpp11BracedList);
- CHECK_PARSE_BOOL(SpaceBeforeCtorInitializerColon);
- CHECK_PARSE_BOOL(SpaceBeforeInheritanceColon);
- CHECK_PARSE_BOOL(SpaceBeforeJsonColon);
- CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon);
- CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets);
- CHECK_PARSE_BOOL(VerilogBreakBetweenInstancePorts);
-
- CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, Enabled);
- CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements,
- AcrossEmptyLines);
- CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AcrossComments);
- CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseArrows);
- CHECK_PARSE_NESTED_BOOL(AlignConsecutiveShortCaseStatements, AlignCaseColons);
- CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Empty);
- CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Inline);
- CHECK_PARSE_NESTED_BOOL(AllowShortFunctionsOnASingleLine, Other);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterEnum);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterFunction);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterNamespace);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterObjCDeclaration);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterStruct);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterUnion);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterExternBlock);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeCatch);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeElse);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeLambdaBody);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeWhile);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyFunction);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyRecord);
- CHECK_PARSE_NESTED_BOOL(BraceWrapping, SplitEmptyNamespace);
- CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtEndOfFile);
- CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtStartOfBlock);
- CHECK_PARSE_NESTED_BOOL(KeepEmptyLines, AtStartOfFile);
- CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterControlStatements);
- CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterForeachMacros);
- CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions,
- AfterFunctionDeclarationName);
- CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions,
- AfterFunctionDefinitionName);
- CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterIfMacros);
- CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterNot);
- CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterOverloadedOperator);
- CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, AfterPlacementOperator);
- CHECK_PARSE_NESTED_BOOL(SpaceBeforeParensOptions, BeforeNonEmptyParentheses);
- CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, ExceptDoubleParentheses);
- CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InCStyleCasts);
- CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InConditionalStatements);
- CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, InEmptyParentheses);
- CHECK_PARSE_NESTED_BOOL(SpacesInParensOptions, Other);
- CHECK_PARSE_NESTED_BOOL(SortIncludes, Enabled);
- CHECK_PARSE_NESTED_BOOL(SortIncludes, IgnoreCase);
- CHECK_PARSE_NESTED_BOOL(SortIncludes, IgnoreExtension);
+TEST_F(DefinitionBlockSeparatorTest, FormatConflict) {
+ FormatStyle Style = getLLVMStyle();
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+ StringRef Code = "class Test {\n"
+ "public:\n"
+ " static void foo() {\n"
+ " int t;\n"
+ " return 1;\n"
+ " }\n"
+ "};";
+ std::vector<tooling::Range> Ranges = {1, tooling::Range(0, Code.size())};
+ EXPECT_EQ(reformat(Style, Code, Ranges, "<stdin>").size(), 0u);
}
-#undef CHECK_PARSE_BOOL
-
-TEST(ConfigParseTest, ParsesConfigurationIntegers) {
- FormatStyle Style = {};
- Style.Language = FormatStyle::LK_Cpp;
-
- CHECK_PARSE_INT(AccessModifierOffset);
- CHECK_PARSE_INT(BracedInitializerIndentWidth);
- CHECK_PARSE_INT(PPIndentWidth);
-
- CHECK_PARSE_UNSIGNED(ColumnLimit);
- CHECK_PARSE_UNSIGNED(ConstructorInitializerIndentWidth);
- CHECK_PARSE_UNSIGNED(ContinuationIndentWidth);
- CHECK_PARSE_UNSIGNED(IndentWidth);
- CHECK_PARSE_UNSIGNED(MaxEmptyLinesToKeep);
- CHECK_PARSE_UNSIGNED(ObjCBlockIndentWidth);
- CHECK_PARSE_UNSIGNED(PenaltyBreakAssignment);
- CHECK_PARSE_UNSIGNED(PenaltyBreakBeforeFirstCallParameter);
- CHECK_PARSE_UNSIGNED(PenaltyBreakBeforeMemberAccess);
- CHECK_PARSE_UNSIGNED(PenaltyBreakComment);
- CHECK_PARSE_UNSIGNED(PenaltyBreakFirstLessLess);
- CHECK_PARSE_UNSIGNED(PenaltyBreakOpenParenthesis);
- CHECK_PARSE_UNSIGNED(PenaltyBreakScopeResolution);
- CHECK_PARSE_UNSIGNED(PenaltyBreakString);
- CHECK_PARSE_UNSIGNED(PenaltyBreakTemplateDeclaration);
- CHECK_PARSE_UNSIGNED(PenaltyExcessCharacter);
- CHECK_PARSE_UNSIGNED(PenaltyIndentedWhitespace);
- CHECK_PARSE_UNSIGNED(PenaltyReturnTypeOnItsOwnLine);
- CHECK_PARSE_UNSIGNED(ShortNamespaceLines);
- CHECK_PARSE_UNSIGNED(SpacesBeforeTrailingComments);
- CHECK_PARSE_UNSIGNED(TabWidth);
+TEST_F(DefinitionBlockSeparatorTest, CommentBlock) {
+ FormatStyle Style = getLLVMStyle();
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+ std::string Prefix = "enum Foo { FOO, BAR };\n"
+ "\n"
+ "/*\n"
+ "test1\n"
+ "test2\n"
+ "*/\n"
+ "int foo(int i, int j) {\n"
+ " int r = i + j;\n"
+ " return r;\n"
+ "}\n";
+ std::string Suffix = "enum Bar { FOOBAR, BARFOO };\n"
+ "\n"
+ "/* Comment block in one line*/\n"
+ "int bar3(int j, int k) {\n"
+ " // A comment\n"
+ " int r = j % k;\n"
+ " return r;\n"
+ "}\n";
+ std::string CommentedCode = "/*\n"
+ "int bar2(int j, int k) {\n"
+ " int r = j / k;\n"
+ " return r;\n"
+ "}\n"
+ "*/\n";
+ verifyFormat(removeEmptyLines(Prefix) + "\n" + CommentedCode + "\n" +
+ removeEmptyLines(Suffix),
+ Style, Prefix + "\n" + CommentedCode + "\n" + Suffix);
+ verifyFormat(removeEmptyLines(Prefix) + "\n" + CommentedCode +
+ removeEmptyLines(Suffix),
+ Style, Prefix + "\n" + CommentedCode + Suffix);
}
-TEST(ConfigParseTest, ParsesConfiguration) {
- FormatStyle Style = {};
- Style.Language = FormatStyle::LK_Cpp;
- CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$");
- CHECK_PARSE("OneLineFormatOffRegex: // ab$", OneLineFormatOffRegex, "// ab$");
-
- Style.QualifierAlignment = FormatStyle::QAS_Right;
- CHECK_PARSE("QualifierAlignment: Leave", QualifierAlignment,
- FormatStyle::QAS_Leave);
- CHECK_PARSE("QualifierAlignment: Right", QualifierAlignment,
- FormatStyle::QAS_Right);
- CHECK_PARSE("QualifierAlignment: Left", QualifierAlignment,
- FormatStyle::QAS_Left);
- CHECK_PARSE("QualifierAlignment: Custom", QualifierAlignment,
- FormatStyle::QAS_Custom);
-
- Style.QualifierOrder.clear();
- CHECK_PARSE("QualifierOrder: [ const, volatile, type ]", QualifierOrder,
- std::vector<std::string>({"const", "volatile", "type"}));
- Style.QualifierOrder.clear();
- CHECK_PARSE("QualifierOrder: [const, type]", QualifierOrder,
- std::vector<std::string>({"const", "type"}));
- Style.QualifierOrder.clear();
- CHECK_PARSE("QualifierOrder: [volatile, type]", QualifierOrder,
- std::vector<std::string>({"volatile", "type"}));
-
-#define CHECK_ALIGN_CONSECUTIVE(FIELD) \
- do { \
- Style.FIELD.Enabled = true; \
- CHECK_PARSE(#FIELD ": None", FIELD, \
- FormatStyle::AlignConsecutiveStyle({})); \
- CHECK_PARSE( \
- #FIELD ": Consecutive", FIELD, \
- FormatStyle::AlignConsecutiveStyle( \
- {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \
- /*AcrossComments=*/false, /*AlignCompound=*/false, \
- /*AlignFunctionDeclarations=*/true, \
- /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
- CHECK_PARSE( \
- #FIELD ": AcrossEmptyLines", FIELD, \
- FormatStyle::AlignConsecutiveStyle( \
- {/*Enabled=*/true, /*AcrossEmptyLines=*/true, \
- /*AcrossComments=*/false, /*AlignCompound=*/false, \
- /*AlignFunctionDeclarations=*/true, \
- /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
- CHECK_PARSE( \
- #FIELD ": AcrossComments", FIELD, \
- FormatStyle::AlignConsecutiveStyle( \
- {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \
- /*AcrossComments=*/true, /*AlignCompound=*/false, \
- /*AlignFunctionDeclarations=*/true, \
- /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
- CHECK_PARSE( \
- #FIELD ": AcrossEmptyLinesAndComments", FIELD, \
- FormatStyle::AlignConsecutiveStyle( \
- {/*Enabled=*/true, /*AcrossEmptyLines=*/true, \
- /*AcrossComments=*/true, /*AlignCompound=*/false, \
- /*AlignFunctionDeclarations=*/true, \
- /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
- /* For backwards compability, false / true should still parse */ \
- CHECK_PARSE(#FIELD ": false", FIELD, \
- FormatStyle::AlignConsecutiveStyle({})); \
- CHECK_PARSE( \
- #FIELD ": true", FIELD, \
- FormatStyle::AlignConsecutiveStyle( \
- {/*Enabled=*/true, /*AcrossEmptyLines=*/false, \
- /*AcrossComments=*/false, /*AlignCompound=*/false, \
- /*AlignFunctionDeclarations=*/true, \
- /*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
- \
- CHECK_PARSE_NESTED_BOOL(FIELD, Enabled); \
- CHECK_PARSE_NESTED_BOOL(FIELD, AcrossEmptyLines); \
- CHECK_PARSE_NESTED_BOOL(FIELD, AcrossComments); \
- CHECK_PARSE_NESTED_BOOL(FIELD, AlignCompound); \
- CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionDeclarations); \
- CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionPointers); \
- CHECK_PARSE_NESTED_BOOL(FIELD, PadOperators); \
- } while (false)
-
- CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveAssignments);
- CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveBitFields);
- CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveMacros);
- CHECK_ALIGN_CONSECUTIVE(AlignConsecutiveDeclarations);
-
-#undef CHECK_ALIGN_CONSECUTIVE
-
- Style.PointerAlignment = FormatStyle::PAS_Middle;
- CHECK_PARSE("PointerAlignment: Left", PointerAlignment,
- FormatStyle::PAS_Left);
- CHECK_PARSE("PointerAlignment: Right", PointerAlignment,
- FormatStyle::PAS_Right);
- CHECK_PARSE("PointerAlignment: Middle", PointerAlignment,
- FormatStyle::PAS_Middle);
- Style.ReferenceAlignment = FormatStyle::RAS_Middle;
- CHECK_PARSE("ReferenceAlignment: Pointer", ReferenceAlignment,
- FormatStyle::RAS_Pointer);
- CHECK_PARSE("ReferenceAlignment: Left", ReferenceAlignment,
- FormatStyle::RAS_Left);
- CHECK_PARSE("ReferenceAlignment: Right", ReferenceAlignment,
- FormatStyle::RAS_Right);
- CHECK_PARSE("ReferenceAlignment: Middle", ReferenceAlignment,
- FormatStyle::RAS_Middle);
- // For backward compatibility:
- CHECK_PARSE("PointerBindsToType: Left", PointerAlignment,
- FormatStyle::PAS_Left);
- CHECK_PARSE("PointerBindsToType: Right", PointerAlignment,
- FormatStyle::PAS_Right);
- CHECK_PARSE("PointerBindsToType: Middle", PointerAlignment,
- FormatStyle::PAS_Middle);
-
- Style.ReflowComments = FormatStyle::RCS_Always;
- CHECK_PARSE("ReflowComments: Never", ReflowComments, FormatStyle::RCS_Never);
- CHECK_PARSE("ReflowComments: IndentOnly", ReflowComments,
- FormatStyle::RCS_IndentOnly);
- CHECK_PARSE("ReflowComments: Always", ReflowComments,
- FormatStyle::RCS_Always);
- // For backward compatibility:
- CHECK_PARSE("ReflowComments: false", ReflowComments, FormatStyle::RCS_Never);
- CHECK_PARSE("ReflowComments: true", ReflowComments, FormatStyle::RCS_Always);
-
- Style.Standard = FormatStyle::LS_Auto;
- CHECK_PARSE("Standard: c++03", Standard, FormatStyle::LS_Cpp03);
- CHECK_PARSE("Standard: c++11", Standard, FormatStyle::LS_Cpp11);
- CHECK_PARSE("Standard: c++14", Standard, FormatStyle::LS_Cpp14);
- CHECK_PARSE("Standard: c++17", Standard, FormatStyle::LS_Cpp17);
- CHECK_PARSE("Standard: c++20", Standard, FormatStyle::LS_Cpp20);
- CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto);
- CHECK_PARSE("Standard: Latest", Standard, FormatStyle::LS_Latest);
- // Legacy aliases:
- CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03);
- CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Latest);
- CHECK_PARSE("Standard: C++03", Standard, FormatStyle::LS_Cpp03);
- CHECK_PARSE("Standard: C++11", Standard, FormatStyle::LS_Cpp11);
-
- Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
- CHECK_PARSE("BreakBeforeBinaryOperators: NonAssignment",
- BreakBeforeBinaryOperators, FormatStyle::BOS_NonAssignment);
- CHECK_PARSE("BreakBeforeBinaryOperators: None", BreakBeforeBinaryOperators,
- FormatStyle::BOS_None);
- CHECK_PARSE("BreakBeforeBinaryOperators: All", BreakBeforeBinaryOperators,
- FormatStyle::BOS_All);
- // For backward compatibility:
- CHECK_PARSE("BreakBeforeBinaryOperators: false", BreakBeforeBinaryOperators,
- FormatStyle::BOS_None);
- CHECK_PARSE("BreakBeforeBinaryOperators: true", BreakBeforeBinaryOperators,
- FormatStyle::BOS_All);
-
- Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
- CHECK_PARSE("BreakBinaryOperations: OnePerLine", BreakBinaryOperations,
- FormatStyle::BreakBinaryOperationsOptions(
- {FormatStyle::BBO_OnePerLine, {}}));
- CHECK_PARSE("BreakBinaryOperations: RespectPrecedence", BreakBinaryOperations,
- FormatStyle::BreakBinaryOperationsOptions(
- {FormatStyle::BBO_RespectPrecedence, {}}));
- CHECK_PARSE(
- "BreakBinaryOperations: Never", BreakBinaryOperations,
- FormatStyle::BreakBinaryOperationsOptions({FormatStyle::BBO_Never, {}}));
-
- // Structured form
- Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
- CHECK_PARSE("BreakBinaryOperations:\n"
- " Default: OnePerLine",
- BreakBinaryOperations,
- FormatStyle::BreakBinaryOperationsOptions(
- {FormatStyle::BBO_OnePerLine, {}}));
-
- Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
- EXPECT_EQ(0, parseConfiguration("BreakBinaryOperations:\n"
- " Default: Never\n"
- " PerOperator:\n"
- " - Operators: ['&&', '||']\n"
- " Style: OnePerLine\n"
- " MinChainLength: 3",
- &Style)
- .value());
- EXPECT_EQ(Style.BreakBinaryOperations.Default, FormatStyle::BBO_Never);
- ASSERT_EQ(Style.BreakBinaryOperations.PerOperator.size(), 1u);
- std::vector<tok::TokenKind> ExpectedOps = {tok::ampamp, tok::pipepipe};
- EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Operators, ExpectedOps);
- EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Style,
- FormatStyle::BBO_OnePerLine);
- EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].MinChainLength, 3u);
-
- // Parse ">" and ">>" which have edge cases: clang-format splits ">>" into
- // two ">" tokens, so ">>" maps to tok::greatergreater while ">" maps to
- // tok::greater.
- Style.BreakBinaryOperations.Default = FormatStyle::BBO_Never;
- EXPECT_EQ(0, parseConfiguration("BreakBinaryOperations:\n"
- " Default: Never\n"
- " PerOperator:\n"
- " - Operators: ['>', '>>']\n"
- " Style: OnePerLine",
- &Style)
- .value());
- ASSERT_EQ(Style.BreakBinaryOperations.PerOperator.size(), 1u);
- std::vector<tok::TokenKind> ExpectedShiftOps = {tok::greater,
- tok::greatergreater};
- EXPECT_EQ(Style.BreakBinaryOperations.PerOperator[0].Operators,
- ExpectedShiftOps);
-
- Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
- CHECK_PARSE("BreakConstructorInitializers: BeforeComma",
- BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
- CHECK_PARSE("BreakConstructorInitializers: AfterColon",
- BreakConstructorInitializers, FormatStyle::BCIS_AfterColon);
- CHECK_PARSE("BreakConstructorInitializers: AfterComma",
- BreakConstructorInitializers, FormatStyle::BCIS_AfterComma);
- CHECK_PARSE("BreakConstructorInitializers: BeforeColon",
- BreakConstructorInitializers, FormatStyle::BCIS_BeforeColon);
- // For backward compatibility:
- CHECK_PARSE("BreakConstructorInitializersBeforeComma: true",
- BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
-
- Style.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
- CHECK_PARSE("BreakInheritanceList: AfterComma", BreakInheritanceList,
- FormatStyle::BILS_AfterComma);
- CHECK_PARSE("BreakInheritanceList: BeforeComma", BreakInheritanceList,
- FormatStyle::BILS_BeforeComma);
- CHECK_PARSE("BreakInheritanceList: AfterColon", BreakInheritanceList,
- FormatStyle::BILS_AfterColon);
- CHECK_PARSE("BreakInheritanceList: BeforeColon", BreakInheritanceList,
- FormatStyle::BILS_BeforeColon);
- // For backward compatibility:
- CHECK_PARSE("BreakBeforeInheritanceComma: true", BreakInheritanceList,
- FormatStyle::BILS_BeforeComma);
-
- Style.BinPackParameters = FormatStyle::BPPS_OnePerLine;
- CHECK_PARSE("BinPackParameters: BinPack", BinPackParameters,
- FormatStyle::BPPS_BinPack);
- CHECK_PARSE("BinPackParameters: OnePerLine", BinPackParameters,
- FormatStyle::BPPS_OnePerLine);
- CHECK_PARSE("BinPackParameters: AlwaysOnePerLine", BinPackParameters,
- FormatStyle::BPPS_AlwaysOnePerLine);
- // For backward compatibility.
- CHECK_PARSE("BinPackParameters: true", BinPackParameters,
- FormatStyle::BPPS_BinPack);
- CHECK_PARSE("BinPackParameters: false", BinPackParameters,
- FormatStyle::BPPS_OnePerLine);
-
- Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
- CHECK_PARSE("PackConstructorInitializers: Never", PackConstructorInitializers,
- FormatStyle::PCIS_Never);
- CHECK_PARSE("PackConstructorInitializers: BinPack",
- PackConstructorInitializers, FormatStyle::PCIS_BinPack);
- CHECK_PARSE("PackConstructorInitializers: CurrentLine",
- PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
- CHECK_PARSE("PackConstructorInitializers: NextLine",
- PackConstructorInitializers, FormatStyle::PCIS_NextLine);
- CHECK_PARSE("PackConstructorInitializers: NextLineOnly",
- PackConstructorInitializers, FormatStyle::PCIS_NextLineOnly);
- // For backward compatibility:
- CHECK_PARSE("BasedOnStyle: Google\n"
- "ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
- "AllowAllConstructorInitializersOnNextLine: false",
- PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
- Style.PackConstructorInitializers = FormatStyle::PCIS_NextLine;
- CHECK_PARSE("BasedOnStyle: Google\n"
- "ConstructorInitializerAllOnOneLineOrOnePerLine: false",
- PackConstructorInitializers, FormatStyle::PCIS_BinPack);
- CHECK_PARSE("ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
- "AllowAllConstructorInitializersOnNextLine: true",
- PackConstructorInitializers, FormatStyle::PCIS_NextLine);
- Style.PackConstructorInitializers = FormatStyle::PCIS_BinPack;
- CHECK_PARSE("ConstructorInitializerAllOnOneLineOrOnePerLine: true\n"
- "AllowAllConstructorInitializersOnNextLine: false",
- PackConstructorInitializers, FormatStyle::PCIS_CurrentLine);
-
- Style.EmptyLineBeforeAccessModifier = FormatStyle::ELBAMS_LogicalBlock;
- CHECK_PARSE("EmptyLineBeforeAccessModifier: Never",
- EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Never);
- CHECK_PARSE("EmptyLineBeforeAccessModifier: Leave",
- EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Leave);
- CHECK_PARSE("EmptyLineBeforeAccessModifier: LogicalBlock",
- EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_LogicalBlock);
- CHECK_PARSE("EmptyLineBeforeAccessModifier: Always",
- EmptyLineBeforeAccessModifier, FormatStyle::ELBAMS_Always);
-
- Style.EnumTrailingComma = FormatStyle::ETC_Insert;
- CHECK_PARSE("EnumTrailingComma: Leave", EnumTrailingComma,
- FormatStyle::ETC_Leave);
- CHECK_PARSE("EnumTrailingComma: Insert", EnumTrailingComma,
- FormatStyle::ETC_Insert);
- CHECK_PARSE("EnumTrailingComma: Remove", EnumTrailingComma,
- FormatStyle::ETC_Remove);
-
- Style.AlignAfterOpenBracket = false;
- CHECK_PARSE("AlignAfterOpenBracket: Align", AlignAfterOpenBracket, true);
- CHECK_PARSE("AlignAfterOpenBracket: DontAlign", AlignAfterOpenBracket, false);
- // For backward compatibility:
- CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak", AlignAfterOpenBracket,
- true);
- CHECK_PARSE("AlignAfterOpenBracket: AlwaysBreak\n"
- "BreakAfterOpenBracketIf: false",
- BreakAfterOpenBracketIf, false);
- CHECK_PARSE("BreakAfterOpenBracketLoop: true\n"
- "AlignAfterOpenBracket: AlwaysBreak",
- BreakAfterOpenBracketLoop, true);
- CHECK_PARSE("AlignAfterOpenBracket: false", AlignAfterOpenBracket, false);
- CHECK_PARSE("AlignAfterOpenBracket: BlockIndent", AlignAfterOpenBracket,
- true);
- Style.AlignAfterOpenBracket = false;
- CHECK_PARSE("AlignAfterOpenBracket: true", AlignAfterOpenBracket, true);
-
- Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
- CHECK_PARSE("AlignEscapedNewlines: DontAlign", AlignEscapedNewlines,
- FormatStyle::ENAS_DontAlign);
- CHECK_PARSE("AlignEscapedNewlines: Left", AlignEscapedNewlines,
- FormatStyle::ENAS_Left);
- CHECK_PARSE("AlignEscapedNewlines: LeftWithLastLine", AlignEscapedNewlines,
- FormatStyle::ENAS_LeftWithLastLine);
- CHECK_PARSE("AlignEscapedNewlines: Right", AlignEscapedNewlines,
- FormatStyle::ENAS_Right);
- // For backward compatibility:
- CHECK_PARSE("AlignEscapedNewlinesLeft: true", AlignEscapedNewlines,
- FormatStyle::ENAS_Left);
- CHECK_PARSE("AlignEscapedNewlinesLeft: false", AlignEscapedNewlines,
- FormatStyle::ENAS_Right);
-
- Style.AlignOperands = FormatStyle::OAS_Align;
- CHECK_PARSE("AlignOperands: DontAlign", AlignOperands,
- FormatStyle::OAS_DontAlign);
- CHECK_PARSE("AlignOperands: Align", AlignOperands, FormatStyle::OAS_Align);
- CHECK_PARSE("AlignOperands: AlignAfterOperator", AlignOperands,
- FormatStyle::OAS_AlignAfterOperator);
- // For backward compatibility:
- CHECK_PARSE("AlignOperands: false", AlignOperands,
- FormatStyle::OAS_DontAlign);
- CHECK_PARSE("AlignOperands: true", AlignOperands, FormatStyle::OAS_Align);
-
- CHECK_PARSE("AlignTrailingComments: Leave", AlignTrailingComments,
- FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Leave, 0, true}));
- CHECK_PARSE("AlignTrailingComments: Always", AlignTrailingComments,
- FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Always, 0, true}));
- CHECK_PARSE("AlignTrailingComments: Never", AlignTrailingComments,
- FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Never, 0, true}));
- // For backwards compatibility
- CHECK_PARSE("AlignTrailingComments: true", AlignTrailingComments,
- FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Always, 0, true}));
- CHECK_PARSE("AlignTrailingComments: false", AlignTrailingComments,
- FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Never, 0, true}));
- CHECK_PARSE_NESTED_VALUE("Kind: Always", AlignTrailingComments, Kind,
- FormatStyle::TCAS_Always);
- CHECK_PARSE_NESTED_VALUE("Kind: Never", AlignTrailingComments, Kind,
- FormatStyle::TCAS_Never);
- CHECK_PARSE_NESTED_VALUE("Kind: Leave", AlignTrailingComments, Kind,
- FormatStyle::TCAS_Leave);
- CHECK_PARSE_NESTED_VALUE("OverEmptyLines: 1234", AlignTrailingComments,
- OverEmptyLines, 1234u);
- CHECK_PARSE_NESTED_BOOL(AlignTrailingComments, AlignPPAndNotPP);
-
- Style.UseTab = FormatStyle::UT_ForIndentation;
- CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);
- CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
- CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always);
- CHECK_PARSE("UseTab: ForContinuationAndIndentation", UseTab,
- FormatStyle::UT_ForContinuationAndIndentation);
- CHECK_PARSE("UseTab: AlignWithSpaces", UseTab,
- FormatStyle::UT_AlignWithSpaces);
- // For backward compatibility:
- CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never);
- CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always);
-
- Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
- CHECK_PARSE("AllowShortBlocksOnASingleLine: Never",
- AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never);
- CHECK_PARSE("AllowShortBlocksOnASingleLine: Empty",
- AllowShortBlocksOnASingleLine, FormatStyle::SBS_Empty);
- CHECK_PARSE("AllowShortBlocksOnASingleLine: Always",
- AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
- // For backward compatibility:
- CHECK_PARSE("AllowShortBlocksOnASingleLine: false",
- AllowShortBlocksOnASingleLine, FormatStyle::SBS_Never);
- CHECK_PARSE("AllowShortBlocksOnASingleLine: true",
- AllowShortBlocksOnASingleLine, FormatStyle::SBS_Always);
-
- CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
- AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle());
- CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
- AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle::setEmptyAndInline());
- CHECK_PARSE("AllowShortFunctionsOnASingleLine: Empty",
- AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle::setEmptyOnly());
- CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
- AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle::setAll());
- CHECK_PARSE("AllowShortFunctionsOnASingleLine: InlineOnly",
- AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle::setInlineOnly());
-
- // For backward compatibility:
- CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
- AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle());
- CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
- AllowShortFunctionsOnASingleLine,
- FormatStyle::ShortFunctionStyle::setAll());
-
- Style.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
- CHECK_PARSE("AllowShortLambdasOnASingleLine: None",
- AllowShortLambdasOnASingleLine, FormatStyle::SLS_None);
- CHECK_PARSE("AllowShortLambdasOnASingleLine: Empty",
- AllowShortLambdasOnASingleLine, FormatStyle::SLS_Empty);
- CHECK_PARSE("AllowShortLambdasOnASingleLine: Inline",
- AllowShortLambdasOnASingleLine, FormatStyle::SLS_Inline);
- CHECK_PARSE("AllowShortLambdasOnASingleLine: All",
- AllowShortLambdasOnASingleLine, FormatStyle::SLS_All);
- // For backward compatibility:
- CHECK_PARSE("AllowShortLambdasOnASingleLine: false",
- AllowShortLambdasOnASingleLine, FormatStyle::SLS_None);
- CHECK_PARSE("AllowShortLambdasOnASingleLine: true",
- AllowShortLambdasOnASingleLine, FormatStyle::SLS_All);
-
- Style.SpaceAroundPointerQualifiers = FormatStyle::SAPQ_Both;
- CHECK_PARSE("SpaceAroundPointerQualifiers: Default",
- SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Default);
- CHECK_PARSE("SpaceAroundPointerQualifiers: Before",
- SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Before);
- CHECK_PARSE("SpaceAroundPointerQualifiers: After",
- SpaceAroundPointerQualifiers, FormatStyle::SAPQ_After);
- CHECK_PARSE("SpaceAroundPointerQualifiers: Both",
- SpaceAroundPointerQualifiers, FormatStyle::SAPQ_Both);
-
- Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
- CHECK_PARSE("SpaceBeforeParens: Never", SpaceBeforeParens,
- FormatStyle::SBPO_Never);
- CHECK_PARSE("SpaceBeforeParens: Always", SpaceBeforeParens,
- FormatStyle::SBPO_Always);
- CHECK_PARSE("SpaceBeforeParens: ControlStatements", SpaceBeforeParens,
- FormatStyle::SBPO_ControlStatements);
- CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptControlMacros",
- SpaceBeforeParens,
- FormatStyle::SBPO_ControlStatementsExceptControlMacros);
- CHECK_PARSE("SpaceBeforeParens: NonEmptyParentheses", SpaceBeforeParens,
- FormatStyle::SBPO_NonEmptyParentheses);
- CHECK_PARSE("SpaceBeforeParens: Custom", SpaceBeforeParens,
- FormatStyle::SBPO_Custom);
- // For backward compatibility:
- CHECK_PARSE("SpaceAfterControlStatementKeyword: false", SpaceBeforeParens,
- FormatStyle::SBPO_Never);
- CHECK_PARSE("SpaceAfterControlStatementKeyword: true", SpaceBeforeParens,
- FormatStyle::SBPO_ControlStatements);
- CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptForEachMacros",
- SpaceBeforeParens,
- FormatStyle::SBPO_ControlStatementsExceptControlMacros);
-
- Style.SpaceInEmptyBraces = FormatStyle::SIEB_Never;
- CHECK_PARSE("SpaceInEmptyBraces: Always", SpaceInEmptyBraces,
- FormatStyle::SIEB_Always);
- CHECK_PARSE("SpaceInEmptyBraces: Block", SpaceInEmptyBraces,
- FormatStyle::SIEB_Block);
- CHECK_PARSE("SpaceInEmptyBraces: Never", SpaceInEmptyBraces,
- FormatStyle::SIEB_Never);
- // For backward compatibility:
- CHECK_PARSE("SpaceInEmptyBlock: true", SpaceInEmptyBraces,
- FormatStyle::SIEB_Block);
-
- // For backward compatibility:
- Style.SpacesInParens = FormatStyle::SIPO_Never;
- Style.SpacesInParensOptions = {};
- CHECK_PARSE("SpacesInParentheses: true", SpacesInParens,
- FormatStyle::SIPO_Custom);
- Style.SpacesInParens = FormatStyle::SIPO_Never;
- Style.SpacesInParensOptions = {};
- CHECK_PARSE(
- "SpacesInParentheses: true", SpacesInParensOptions,
- FormatStyle::SpacesInParensCustom(false, true, false, false, true));
- Style.SpacesInParens = FormatStyle::SIPO_Never;
- Style.SpacesInParensOptions = {};
- CHECK_PARSE(
- "SpacesInConditionalStatement: true", SpacesInParensOptions,
- FormatStyle::SpacesInParensCustom(false, true, false, false, false));
- Style.SpacesInParens = FormatStyle::SIPO_Never;
- Style.SpacesInParensOptions = {};
- CHECK_PARSE(
- "SpacesInCStyleCastParentheses: true", SpacesInParensOptions,
- FormatStyle::SpacesInParensCustom(false, false, true, false, false));
- Style.SpacesInParens = FormatStyle::SIPO_Never;
- Style.SpacesInParensOptions = {};
- CHECK_PARSE(
- "SpaceInEmptyParentheses: true", SpacesInParensOptions,
- FormatStyle::SpacesInParensCustom(false, false, false, true, false));
- Style.SpacesInParens = FormatStyle::SIPO_Never;
- Style.SpacesInParensOptions = {};
-
- Style.ColumnLimit = 123;
- FormatStyle BaseStyle = getLLVMStyle();
- CHECK_PARSE("BasedOnStyle: LLVM", ColumnLimit, BaseStyle.ColumnLimit);
- CHECK_PARSE("BasedOnStyle: LLVM\nColumnLimit: 1234", ColumnLimit, 1234u);
-
- Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
- CHECK_PARSE("BreakBeforeBraces: Attach", BreakBeforeBraces,
- FormatStyle::BS_Attach);
- CHECK_PARSE("BreakBeforeBraces: Linux", BreakBeforeBraces,
- FormatStyle::BS_Linux);
- CHECK_PARSE("BreakBeforeBraces: Mozilla", BreakBeforeBraces,
- FormatStyle::BS_Mozilla);
- CHECK_PARSE("BreakBeforeBraces: Stroustrup", BreakBeforeBraces,
- FormatStyle::BS_Stroustrup);
- CHECK_PARSE("BreakBeforeBraces: Allman", BreakBeforeBraces,
- FormatStyle::BS_Allman);
- CHECK_PARSE("BreakBeforeBraces: Whitesmiths", BreakBeforeBraces,
- FormatStyle::BS_Whitesmiths);
- CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU);
- CHECK_PARSE("BreakBeforeBraces: WebKit", BreakBeforeBraces,
- FormatStyle::BS_WebKit);
- CHECK_PARSE("BreakBeforeBraces: Custom", BreakBeforeBraces,
- FormatStyle::BS_Custom);
-
- Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Never;
- CHECK_PARSE("BraceWrapping:\n"
- " AfterControlStatement: MultiLine",
- BraceWrapping.AfterControlStatement,
- FormatStyle::BWACS_MultiLine);
- CHECK_PARSE("BraceWrapping:\n"
- " AfterControlStatement: Always",
- BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Always);
- CHECK_PARSE("BraceWrapping:\n"
- " AfterControlStatement: Never",
- BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never);
- // For backward compatibility:
- CHECK_PARSE("BraceWrapping:\n"
- " AfterControlStatement: true",
- BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Always);
- CHECK_PARSE("BraceWrapping:\n"
- " AfterControlStatement: false",
- BraceWrapping.AfterControlStatement, FormatStyle::BWACS_Never);
-
- Style.BreakAfterReturnType = FormatStyle::RTBS_All;
- CHECK_PARSE("BreakAfterReturnType: None", BreakAfterReturnType,
- FormatStyle::RTBS_None);
- CHECK_PARSE("BreakAfterReturnType: Automatic", BreakAfterReturnType,
- FormatStyle::RTBS_Automatic);
- CHECK_PARSE("BreakAfterReturnType: ExceptShortType", BreakAfterReturnType,
- FormatStyle::RTBS_ExceptShortType);
- CHECK_PARSE("BreakAfterReturnType: All", BreakAfterReturnType,
- FormatStyle::RTBS_All);
- CHECK_PARSE("BreakAfterReturnType: TopLevel", BreakAfterReturnType,
- FormatStyle::RTBS_TopLevel);
- CHECK_PARSE("BreakAfterReturnType: AllDefinitions", BreakAfterReturnType,
- FormatStyle::RTBS_AllDefinitions);
- CHECK_PARSE("BreakAfterReturnType: TopLevelDefinitions", BreakAfterReturnType,
- FormatStyle::RTBS_TopLevelDefinitions);
- // For backward compatibility:
- CHECK_PARSE("AlwaysBreakAfterReturnType: None", BreakAfterReturnType,
- FormatStyle::RTBS_None);
- CHECK_PARSE("AlwaysBreakAfterReturnType: Automatic", BreakAfterReturnType,
- FormatStyle::RTBS_Automatic);
- CHECK_PARSE("AlwaysBreakAfterReturnType: ExceptShortType",
- BreakAfterReturnType, FormatStyle::RTBS_ExceptShortType);
- CHECK_PARSE("AlwaysBreakAfterReturnType: All", BreakAfterReturnType,
- FormatStyle::RTBS_All);
- CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevel", BreakAfterReturnType,
- FormatStyle::RTBS_TopLevel);
- CHECK_PARSE("AlwaysBreakAfterReturnType: AllDefinitions",
- BreakAfterReturnType, FormatStyle::RTBS_AllDefinitions);
- CHECK_PARSE("AlwaysBreakAfterReturnType: TopLevelDefinitions",
- BreakAfterReturnType, FormatStyle::RTBS_TopLevelDefinitions);
-
- Style.BreakTemplateDeclarations = FormatStyle::BTDS_Yes;
- CHECK_PARSE("BreakTemplateDeclarations: Leave", BreakTemplateDeclarations,
- FormatStyle::BTDS_Leave);
- CHECK_PARSE("BreakTemplateDeclarations: No", BreakTemplateDeclarations,
- FormatStyle::BTDS_No);
- CHECK_PARSE("BreakTemplateDeclarations: MultiLine", BreakTemplateDeclarations,
- FormatStyle::BTDS_MultiLine);
- CHECK_PARSE("BreakTemplateDeclarations: Yes", BreakTemplateDeclarations,
- FormatStyle::BTDS_Yes);
- CHECK_PARSE("BreakTemplateDeclarations: false", BreakTemplateDeclarations,
- FormatStyle::BTDS_MultiLine);
- CHECK_PARSE("BreakTemplateDeclarations: true", BreakTemplateDeclarations,
- FormatStyle::BTDS_Yes);
- // For backward compatibility:
- CHECK_PARSE("AlwaysBreakTemplateDeclarations: Leave",
- BreakTemplateDeclarations, FormatStyle::BTDS_Leave);
- CHECK_PARSE("AlwaysBreakTemplateDeclarations: No", BreakTemplateDeclarations,
- FormatStyle::BTDS_No);
- CHECK_PARSE("AlwaysBreakTemplateDeclarations: MultiLine",
- BreakTemplateDeclarations, FormatStyle::BTDS_MultiLine);
- CHECK_PARSE("AlwaysBreakTemplateDeclarations: Yes", BreakTemplateDeclarations,
- FormatStyle::BTDS_Yes);
- CHECK_PARSE("AlwaysBreakTemplateDeclarations: false",
- BreakTemplateDeclarations, FormatStyle::BTDS_MultiLine);
- CHECK_PARSE("AlwaysBreakTemplateDeclarations: true",
- BreakTemplateDeclarations, FormatStyle::BTDS_Yes);
-
- Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
- CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None",
- AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_None);
- CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: All",
- AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_All);
- CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: TopLevel",
- AlwaysBreakAfterDefinitionReturnType,
- FormatStyle::DRTBS_TopLevel);
-
- Style.NamespaceIndentation = FormatStyle::NI_All;
- CHECK_PARSE("NamespaceIndentation: None", NamespaceIndentation,
- FormatStyle::NI_None);
- CHECK_PARSE("NamespaceIndentation: Inner", NamespaceIndentation,
- FormatStyle::NI_Inner);
- CHECK_PARSE("NamespaceIndentation: All", NamespaceIndentation,
- FormatStyle::NI_All);
-
- Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_OnlyFirstIf;
- CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Never",
- AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never);
- CHECK_PARSE("AllowShortIfStatementsOnASingleLine: WithoutElse",
- AllowShortIfStatementsOnASingleLine,
- FormatStyle::SIS_WithoutElse);
- CHECK_PARSE("AllowShortIfStatementsOnASingleLine: OnlyFirstIf",
- AllowShortIfStatementsOnASingleLine,
- FormatStyle::SIS_OnlyFirstIf);
- CHECK_PARSE("AllowShortIfStatementsOnASingleLine: AllIfsAndElse",
- AllowShortIfStatementsOnASingleLine,
- FormatStyle::SIS_AllIfsAndElse);
- CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Always",
- AllowShortIfStatementsOnASingleLine,
- FormatStyle::SIS_OnlyFirstIf);
- CHECK_PARSE("AllowShortIfStatementsOnASingleLine: false",
- AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never);
- CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
- AllowShortIfStatementsOnASingleLine,
- FormatStyle::SIS_WithoutElse);
-
- Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
- CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock,
- FormatStyle::IEBS_AfterExternBlock);
- CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock,
- FormatStyle::IEBS_Indent);
- CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock,
- FormatStyle::IEBS_NoIndent);
- CHECK_PARSE("IndentExternBlock: true", IndentExternBlock,
- FormatStyle::IEBS_Indent);
- CHECK_PARSE("IndentExternBlock: false", IndentExternBlock,
- FormatStyle::IEBS_NoIndent);
-
- Style.IndentGotoLabels = FormatStyle::IGLS_OuterIndent;
- CHECK_PARSE("IndentGotoLabels: NoIndent", IndentGotoLabels,
- FormatStyle::IGLS_NoIndent);
- CHECK_PARSE("IndentGotoLabels: OuterIndent", IndentGotoLabels,
- FormatStyle::IGLS_OuterIndent);
- CHECK_PARSE("IndentGotoLabels: InnerIndent", IndentGotoLabels,
- FormatStyle::IGLS_InnerIndent);
- CHECK_PARSE("IndentGotoLabels: HalfIndent", IndentGotoLabels,
- FormatStyle::IGLS_HalfIndent);
- CHECK_PARSE("IndentGotoLabels: false", IndentGotoLabels,
- FormatStyle::IGLS_NoIndent);
- CHECK_PARSE("IndentGotoLabels: true", IndentGotoLabels,
- FormatStyle::IGLS_OuterIndent);
-
- Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
- CHECK_PARSE("BitFieldColonSpacing: Both", BitFieldColonSpacing,
- FormatStyle::BFCS_Both);
- CHECK_PARSE("BitFieldColonSpacing: None", BitFieldColonSpacing,
- FormatStyle::BFCS_None);
- CHECK_PARSE("BitFieldColonSpacing: Before", BitFieldColonSpacing,
- FormatStyle::BFCS_Before);
- CHECK_PARSE("BitFieldColonSpacing: After", BitFieldColonSpacing,
- FormatStyle::BFCS_After);
-
- Style.SortJavaStaticImport = FormatStyle::SJSIO_Before;
- CHECK_PARSE("SortJavaStaticImport: After", SortJavaStaticImport,
- FormatStyle::SJSIO_After);
- CHECK_PARSE("SortJavaStaticImport: Before", SortJavaStaticImport,
- FormatStyle::SJSIO_Before);
-
- Style.SortUsingDeclarations = FormatStyle::SUD_LexicographicNumeric;
- CHECK_PARSE("SortUsingDeclarations: Never", SortUsingDeclarations,
- FormatStyle::SUD_Never);
- CHECK_PARSE("SortUsingDeclarations: Lexicographic", SortUsingDeclarations,
- FormatStyle::SUD_Lexicographic);
- CHECK_PARSE("SortUsingDeclarations: LexicographicNumeric",
- SortUsingDeclarations, FormatStyle::SUD_LexicographicNumeric);
- // For backward compatibility:
- CHECK_PARSE("SortUsingDeclarations: false", SortUsingDeclarations,
- FormatStyle::SUD_Never);
- CHECK_PARSE("SortUsingDeclarations: true", SortUsingDeclarations,
- FormatStyle::SUD_LexicographicNumeric);
-
- CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Never",
- WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Never);
- CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Always",
- WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Always);
- CHECK_PARSE("WrapNamespaceBodyWithEmptyLines: Leave",
- WrapNamespaceBodyWithEmptyLines, FormatStyle::WNBWELS_Leave);
-
- // FIXME: This is required because parsing a configuration simply overwrites
- // the first N elements of the list instead of resetting it.
- Style.ForEachMacros.clear();
- std::vector<std::string> BoostForeach;
- BoostForeach.push_back("BOOST_FOREACH");
- CHECK_PARSE("ForEachMacros: [BOOST_FOREACH]", ForEachMacros, BoostForeach);
- std::vector<std::string> BoostAndQForeach;
- BoostAndQForeach.push_back("BOOST_FOREACH");
- BoostAndQForeach.push_back("Q_FOREACH");
- CHECK_PARSE("ForEachMacros: [BOOST_FOREACH, Q_FOREACH]", ForEachMacros,
- BoostAndQForeach);
-
- Style.IfMacros.clear();
- std::vector<std::string> CustomIfs;
- CustomIfs.push_back("MYIF");
- CHECK_PARSE("IfMacros: [MYIF]", IfMacros, CustomIfs);
-
- Style.AttributeMacros.clear();
- CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros,
- std::vector<std::string>{"__capability"});
- CHECK_PARSE(
- "BasedOnStyle: Google", AttributeMacros,
- std::vector<std::string>({"__capability", "absl_nonnull", "absl_nullable",
- "absl_nullability_unknown"}));
- Style.AttributeMacros.clear();
- CHECK_PARSE("AttributeMacros: [attr1, attr2]", AttributeMacros,
- std::vector<std::string>({"attr1", "attr2"}));
-
- Style.StatementAttributeLikeMacros.clear();
- CHECK_PARSE("StatementAttributeLikeMacros: [emit,Q_EMIT]",
- StatementAttributeLikeMacros,
- std::vector<std::string>({"emit", "Q_EMIT"}));
-
- Style.Macros.clear();
- CHECK_PARSE("{Macros: [foo]}", Macros, std::vector<std::string>({"foo"}));
- std::vector<std::string> GoogleMacros;
- GoogleMacros.push_back("ASSIGN_OR_RETURN(a, b)=a = (b)");
- GoogleMacros.push_back("ASSIGN_OR_RETURN(a, b, c)=a = (b); if (x) return c");
- CHECK_PARSE("BasedOnStyle: Google", Macros, GoogleMacros);
-
- Style.StatementMacros.clear();
- CHECK_PARSE("StatementMacros: [QUNUSED]", StatementMacros,
- std::vector<std::string>{"QUNUSED"});
- CHECK_PARSE("StatementMacros: [QUNUSED, QT_REQUIRE_VERSION]", StatementMacros,
- std::vector<std::string>({"QUNUSED", "QT_REQUIRE_VERSION"}));
-
- CHECK_PARSE_LIST(JavaImportGroups);
- CHECK_PARSE_LIST(MacrosSkippedByRemoveParentheses);
- CHECK_PARSE_LIST(NamespaceMacros);
- CHECK_PARSE_LIST(ObjCPropertyAttributeOrder);
- CHECK_PARSE_LIST(TableGenBreakingDAGArgOperators);
- CHECK_PARSE_LIST(TemplateNames);
- CHECK_PARSE_LIST(TypeNames);
- CHECK_PARSE_LIST(TypenameMacros);
- CHECK_PARSE_LIST(VariableTemplates);
-
- Style.WhitespaceSensitiveMacros.clear();
- CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE]",
- WhitespaceSensitiveMacros, std::vector<std::string>{"STRINGIZE"});
- CHECK_PARSE("WhitespaceSensitiveMacros: [STRINGIZE, ASSERT]",
- WhitespaceSensitiveMacros,
- std::vector<std::string>({"STRINGIZE", "ASSERT"}));
- Style.WhitespaceSensitiveMacros.clear();
- CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE']",
- WhitespaceSensitiveMacros, std::vector<std::string>{"STRINGIZE"});
- CHECK_PARSE("WhitespaceSensitiveMacros: ['STRINGIZE', 'ASSERT']",
- WhitespaceSensitiveMacros,
- std::vector<std::string>({"STRINGIZE", "ASSERT"}));
-
- Style.IncludeStyle.IncludeCategories.clear();
- std::vector<tooling::IncludeStyle::IncludeCategory> ExpectedCategories = {
- {"abc/.*", 2, 0, false}, {".*", 1, 0, true}};
- CHECK_PARSE("IncludeCategories:\n"
- " - Regex: abc/.*\n"
- " Priority: 2\n"
- " - Regex: .*\n"
- " Priority: 1\n"
- " CaseSensitive: true",
- IncludeStyle.IncludeCategories, ExpectedCategories);
- CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeStyle.IncludeIsMainRegex,
- "abc$");
- CHECK_PARSE("IncludeIsMainSourceRegex: 'abc$'",
- IncludeStyle.IncludeIsMainSourceRegex, "abc$");
-
- Style.SortIncludes = {};
- CHECK_PARSE(
- "SortIncludes: true", SortIncludes,
- FormatStyle::SortIncludesOptions(
- {/*Enabled=*/true, /*IgnoreCase=*/false, /*IgnoreExtension=*/false}));
- CHECK_PARSE("SortIncludes: false", SortIncludes,
- FormatStyle::SortIncludesOptions({}));
- CHECK_PARSE(
- "SortIncludes: CaseInsensitive", SortIncludes,
- FormatStyle::SortIncludesOptions(
- {/*Enabled=*/true, /*IgnoreCase=*/true, /*IgnoreExtension=*/false}));
- CHECK_PARSE(
- "SortIncludes: CaseSensitive", SortIncludes,
- FormatStyle::SortIncludesOptions(
- {/*Enabled=*/true, /*IgnoreCase=*/false, /*IgnoreExtension=*/false}));
- CHECK_PARSE("SortIncludes: Never", SortIncludes,
- FormatStyle::SortIncludesOptions({}));
-
- Style.RawStringFormats.clear();
- std::vector<FormatStyle::RawStringFormat> ExpectedRawStringFormats = {
- {
- FormatStyle::LK_TextProto,
- {"pb", "proto"},
- {"PARSE_TEXT_PROTO"},
- /*CanonicalDelimiter=*/"",
- "llvm",
- },
- {
- FormatStyle::LK_Cpp,
- {"cc", "cpp"},
- {"C_CODEBLOCK", "CPPEVAL"},
- /*CanonicalDelimiter=*/"cc",
- /*BasedOnStyle=*/"",
- },
+TEST_F(DefinitionBlockSeparatorTest, UntouchBlockStartStyle) {
+ // Returns a std::pair of two strings, with the first one for passing into
+ // Always test and the second one be the expected result of the first string.
+ auto MakeUntouchTest = [&](std::string BlockHeader, std::string BlockChanger,
+ std::string BlockFooter, bool BlockEndNewLine) {
+ std::string CodePart1 = "enum Foo { FOO, BAR };\n"
+ "\n"
+ "/*\n"
+ "test1\n"
+ "test2\n"
+ "*/\n"
+ "int foo(int i, int j) {\n"
+ " int r = i + j;\n"
+ " return r;\n"
+ "}\n";
+ std::string CodePart2 = "/* Comment block in one line*/\n"
+ "enum Bar { FOOBAR, BARFOO };\n"
+ "\n"
+ "int bar3(int j, int k) {\n"
+ " // A comment\n"
+ " int r = j % k;\n"
+ " return r;\n"
+ "}\n";
+ std::string CodePart3 = "int bar2(int j, int k) {\n"
+ " int r = j / k;\n"
+ " return r;\n"
+ "}\n";
+ std::string ConcatAll = BlockHeader + CodePart1 + BlockChanger + CodePart2 +
+ BlockFooter + (BlockEndNewLine ? "\n" : "") +
+ CodePart3;
+ return std::make_pair(BlockHeader + removeEmptyLines(CodePart1) +
+ BlockChanger + removeEmptyLines(CodePart2) +
+ BlockFooter + removeEmptyLines(CodePart3),
+ ConcatAll);
};
- CHECK_PARSE("RawStringFormats:\n"
- " - Language: TextProto\n"
- " Delimiters:\n"
- " - 'pb'\n"
- " - 'proto'\n"
- " EnclosingFunctions:\n"
- " - 'PARSE_TEXT_PROTO'\n"
- " BasedOnStyle: llvm\n"
- " - Language: Cpp\n"
- " Delimiters:\n"
- " - 'cc'\n"
- " - 'cpp'\n"
- " EnclosingFunctions:\n"
- " - 'C_CODEBLOCK'\n"
- " - 'CPPEVAL'\n"
- " CanonicalDelimiter: 'cc'",
- RawStringFormats, ExpectedRawStringFormats);
-
- CHECK_PARSE("SpacesInLineCommentPrefix:\n"
- " Minimum: 0\n"
- " Maximum: 0",
- SpacesInLineCommentPrefix.Minimum, 0u);
- EXPECT_EQ(Style.SpacesInLineCommentPrefix.Maximum, 0u);
- Style.SpacesInLineCommentPrefix.Minimum = 1;
- CHECK_PARSE("SpacesInLineCommentPrefix:\n"
- " Minimum: 2",
- SpacesInLineCommentPrefix.Minimum, 0u);
- CHECK_PARSE("SpacesInLineCommentPrefix:\n"
- " Maximum: -1",
- SpacesInLineCommentPrefix.Maximum, -1u);
- CHECK_PARSE("SpacesInLineCommentPrefix:\n"
- " Minimum: 2",
- SpacesInLineCommentPrefix.Minimum, 2u);
- CHECK_PARSE("SpacesInLineCommentPrefix:\n"
- " Maximum: 1",
- SpacesInLineCommentPrefix.Maximum, 1u);
- EXPECT_EQ(Style.SpacesInLineCommentPrefix.Minimum, 1u);
-
- Style.SpacesInAngles = FormatStyle::SIAS_Always;
- CHECK_PARSE("SpacesInAngles: Never", SpacesInAngles, FormatStyle::SIAS_Never);
- CHECK_PARSE("SpacesInAngles: Always", SpacesInAngles,
- FormatStyle::SIAS_Always);
- CHECK_PARSE("SpacesInAngles: Leave", SpacesInAngles, FormatStyle::SIAS_Leave);
- // For backward compatibility:
- CHECK_PARSE("SpacesInAngles: false", SpacesInAngles, FormatStyle::SIAS_Never);
- CHECK_PARSE("SpacesInAngles: true", SpacesInAngles, FormatStyle::SIAS_Always);
-
- CHECK_PARSE("RequiresClausePosition: WithPreceding", RequiresClausePosition,
- FormatStyle::RCPS_WithPreceding);
- CHECK_PARSE("RequiresClausePosition: WithFollowing", RequiresClausePosition,
- FormatStyle::RCPS_WithFollowing);
- CHECK_PARSE("RequiresClausePosition: SingleLine", RequiresClausePosition,
- FormatStyle::RCPS_SingleLine);
- CHECK_PARSE("RequiresClausePosition: OwnLine", RequiresClausePosition,
- FormatStyle::RCPS_OwnLine);
-
- CHECK_PARSE("BreakBeforeConceptDeclarations: Never",
- BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Never);
- CHECK_PARSE("BreakBeforeConceptDeclarations: Always",
- BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Always);
- CHECK_PARSE("BreakBeforeConceptDeclarations: Allowed",
- BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Allowed);
- // For backward compatibility:
- CHECK_PARSE("BreakBeforeConceptDeclarations: true",
- BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Always);
- CHECK_PARSE("BreakBeforeConceptDeclarations: false",
- BreakBeforeConceptDeclarations, FormatStyle::BBCDS_Allowed);
-
- CHECK_PARSE("BreakAfterAttributes: Always", BreakAfterAttributes,
- FormatStyle::ABS_Always);
- CHECK_PARSE("BreakAfterAttributes: Leave", BreakAfterAttributes,
- FormatStyle::ABS_Leave);
- CHECK_PARSE("BreakAfterAttributes: Never", BreakAfterAttributes,
- FormatStyle::ABS_Never);
-
- const auto DefaultLineEnding = FormatStyle::LE_DeriveLF;
- CHECK_PARSE("LineEnding: LF", LineEnding, FormatStyle::LE_LF);
- CHECK_PARSE("LineEnding: CRLF", LineEnding, FormatStyle::LE_CRLF);
- CHECK_PARSE("LineEnding: DeriveCRLF", LineEnding, FormatStyle::LE_DeriveCRLF);
- CHECK_PARSE("LineEnding: DeriveLF", LineEnding, DefaultLineEnding);
- // For backward compatibility:
- CHECK_PARSE("DeriveLineEnding: false", LineEnding, FormatStyle::LE_LF);
- Style.LineEnding = DefaultLineEnding;
- CHECK_PARSE("DeriveLineEnding: false\n"
- "UseCRLF: true",
- LineEnding, FormatStyle::LE_CRLF);
- Style.LineEnding = DefaultLineEnding;
- CHECK_PARSE("UseCRLF: true", LineEnding, FormatStyle::LE_DeriveCRLF);
-
- CHECK_PARSE("RemoveParentheses: MultipleParentheses", RemoveParentheses,
- FormatStyle::RPS_MultipleParentheses);
- CHECK_PARSE("RemoveParentheses: ReturnStatement", RemoveParentheses,
- FormatStyle::RPS_ReturnStatement);
- CHECK_PARSE("RemoveParentheses: Leave", RemoveParentheses,
- FormatStyle::RPS_Leave);
-
- CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: Always",
- AllowBreakBeforeNoexceptSpecifier, FormatStyle::BBNSS_Always);
- CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: OnlyWithParen",
- AllowBreakBeforeNoexceptSpecifier,
- FormatStyle::BBNSS_OnlyWithParen);
- CHECK_PARSE("AllowBreakBeforeNoexceptSpecifier: Never",
- AllowBreakBeforeNoexceptSpecifier, FormatStyle::BBNSS_Never);
-
- Style.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
- CHECK_PARSE("SeparateDefinitionBlocks: Always", SeparateDefinitionBlocks,
- FormatStyle::SDS_Always);
- CHECK_PARSE("SeparateDefinitionBlocks: Leave", SeparateDefinitionBlocks,
- FormatStyle::SDS_Leave);
- CHECK_PARSE("SeparateDefinitionBlocks: Never", SeparateDefinitionBlocks,
- FormatStyle::SDS_Never);
-
- CHECK_PARSE("Cpp11BracedListStyle: Block", Cpp11BracedListStyle,
- FormatStyle::BLS_Block);
- CHECK_PARSE("Cpp11BracedListStyle: FunctionCall", Cpp11BracedListStyle,
- FormatStyle::BLS_FunctionCall);
- CHECK_PARSE("Cpp11BracedListStyle: AlignFirstComment", Cpp11BracedListStyle,
- FormatStyle::BLS_AlignFirstComment);
- // For backward compatibility:
- CHECK_PARSE("Cpp11BracedListStyle: false", Cpp11BracedListStyle,
- FormatStyle::BLS_Block);
- CHECK_PARSE("Cpp11BracedListStyle: true", Cpp11BracedListStyle,
- FormatStyle::BLS_AlignFirstComment);
-
- constexpr FormatStyle::IntegerLiteralSeparatorStyle
- ExpectedIntegerLiteralSeparatorStyle{/*Binary=*/2,
- /*BinaryMinDigitInsert=*/5,
- /*BinaryMaxDigitRemove=*/2,
- /*Decimal=*/6,
- /*DecimalMinDigitInsert=*/6,
- /*DecimalMaxDigitRemove=*/3,
- /*Hex=*/4,
- /*HexMinDigitInsert=*/2,
- /*HexMaxDigitRemove=*/1};
- CHECK_PARSE("IntegerLiteralSeparator:\n"
- " Binary: 2\n"
- " BinaryMinDigitsInsert: 5\n"
- " BinaryMaxDigitsRemove: 2\n"
- " Decimal: 6\n"
- " DecimalMinDigitsInsert: 6\n"
- " DecimalMaxDigitsRemove: 3\n"
- " Hex: 4\n"
- " HexMinDigitsInsert: 2\n"
- " HexMaxDigitsRemove: 1",
- IntegerLiteralSeparator, ExpectedIntegerLiteralSeparatorStyle);
-
- // Backward compatibility:
- CHECK_PARSE_NESTED_VALUE("BinaryMinDigits: 6", IntegerLiteralSeparator,
- BinaryMinDigitsInsert, 6);
- CHECK_PARSE_NESTED_VALUE("DecimalMinDigits: 5", IntegerLiteralSeparator,
- DecimalMinDigitsInsert, 5);
- CHECK_PARSE_NESTED_VALUE("HexMinDigits: 5", IntegerLiteralSeparator,
- HexMinDigitsInsert, 5);
+ FormatStyle AlwaysStyle = getLLVMStyle();
+ AlwaysStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+
+ FormatStyle NeverStyle = getLLVMStyle();
+ NeverStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
+
+ auto TestKit = MakeUntouchTest("/* FOOBAR */\n"
+ "#ifdef FOO\n\n",
+ "\n#elifndef BAR\n\n", "\n#endif\n\n", false);
+ verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
+ verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
+
+ TestKit = MakeUntouchTest("/* FOOBAR */\n"
+ "#ifdef FOO\n",
+ "#elifndef BAR\n", "#endif\n", false);
+ verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
+ verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
+
+ TestKit = MakeUntouchTest("namespace Ns {\n\n",
+ "\n} // namespace Ns\n\n"
+ "namespace {\n\n",
+ "\n} // namespace\n", true);
+ verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
+ verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
+
+ TestKit = MakeUntouchTest("namespace Ns {\n",
+ "} // namespace Ns\n\n"
+ "namespace {\n",
+ "} // namespace\n", true);
+ verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
+ verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
}
-TEST(ConfigParseTest, ParsesConfigurationWithLanguages) {
- FormatStyle Style = {};
- Style.Language = FormatStyle::LK_Cpp;
- CHECK_PARSE("Language: Cpp\n"
- "IndentWidth: 12",
- IndentWidth, 12u);
- EXPECT_EQ(parseConfiguration("Language: JavaScript\n"
- "IndentWidth: 34",
- &Style),
- ParseError::Unsuitable);
- FormatStyle BinPackedTCS = {};
- BinPackedTCS.Language = FormatStyle::LK_JavaScript;
- EXPECT_EQ(parseConfiguration("BinPackArguments: true\n"
- "InsertTrailingCommas: Wrapped",
- &BinPackedTCS),
- ParseError::BinPackTrailingCommaConflict);
- EXPECT_EQ(12u, Style.IndentWidth);
- CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
- EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
-
- Style.Language = FormatStyle::LK_JavaScript;
- CHECK_PARSE("Language: JavaScript\n"
- "IndentWidth: 12",
- IndentWidth, 12u);
- CHECK_PARSE("IndentWidth: 23", IndentWidth, 23u);
- EXPECT_EQ(parseConfiguration("Language: Cpp\n"
- "IndentWidth: 34",
- &Style),
- ParseError::Unsuitable);
- EXPECT_EQ(23u, Style.IndentWidth);
- CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
- EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
-
- CHECK_PARSE("BasedOnStyle: LLVM\n"
- "IndentWidth: 67",
- IndentWidth, 67u);
-
- CHECK_PARSE("---\n"
- "Language: JavaScript\n"
- "IndentWidth: 12\n"
- "---\n"
- "Language: Cpp\n"
- "IndentWidth: 34\n"
- "...\n",
- IndentWidth, 12u);
-
- Style.Language = FormatStyle::LK_Cpp;
- CHECK_PARSE("---\n"
- "Language: JavaScript\n"
- "IndentWidth: 12\n"
- "---\n"
- "Language: Cpp\n"
- "IndentWidth: 34\n"
- "...\n",
- IndentWidth, 34u);
- CHECK_PARSE("---\n"
- "IndentWidth: 78\n"
- "---\n"
- "Language: JavaScript\n"
- "IndentWidth: 56\n"
- "...\n",
- IndentWidth, 78u);
-
- Style.ColumnLimit = 123;
- Style.IndentWidth = 234;
- Style.BreakBeforeBraces = FormatStyle::BS_Linux;
- Style.TabWidth = 345;
- EXPECT_FALSE(parseConfiguration("---\n"
- "IndentWidth: 456\n"
- "BreakBeforeBraces: Allman\n"
- "---\n"
- "Language: JavaScript\n"
- "IndentWidth: 111\n"
- "TabWidth: 111\n"
- "---\n"
- "Language: Cpp\n"
- "BreakBeforeBraces: Stroustrup\n"
- "TabWidth: 789\n"
- "...\n",
- &Style));
- EXPECT_EQ(123u, Style.ColumnLimit);
- EXPECT_EQ(456u, Style.IndentWidth);
- EXPECT_EQ(FormatStyle::BS_Stroustrup, Style.BreakBeforeBraces);
- EXPECT_EQ(789u, Style.TabWidth);
-
- EXPECT_EQ(parseConfiguration("---\n"
- "Language: JavaScript\n"
- "IndentWidth: 56\n"
- "---\n"
- "IndentWidth: 78\n"
- "...\n",
- &Style),
- ParseError::Error);
- EXPECT_EQ(parseConfiguration("---\n"
- "Language: JavaScript\n"
- "IndentWidth: 56\n"
- "---\n"
- "Language: JavaScript\n"
- "IndentWidth: 78\n"
- "...\n",
- &Style),
- ParseError::Error);
-
- EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
-
- Style.Language = FormatStyle::LK_Verilog;
- CHECK_PARSE("---\n"
- "Language: Verilog\n"
- "IndentWidth: 12\n"
- "---\n"
- "Language: Cpp\n"
- "IndentWidth: 34\n"
- "...\n",
- IndentWidth, 12u);
- CHECK_PARSE("---\n"
- "IndentWidth: 78\n"
- "---\n"
- "Language: Verilog\n"
- "IndentWidth: 56\n"
- "...\n",
- IndentWidth, 56u);
-}
-
-TEST(ConfigParseTest, AllowCommentOnlyConfigFile) {
- FormatStyle Style = {};
- Style.Language = FormatStyle::LK_Cpp;
- EXPECT_EQ(parseConfiguration("#Language: C", &Style), ParseError::Success);
- EXPECT_EQ(Style.Language, FormatStyle::LK_Cpp);
-}
-
-TEST(ConfigParseTest, AllowCppForC) {
- FormatStyle Style = {};
- Style.Language = FormatStyle::LK_C;
- EXPECT_EQ(parseConfiguration("Language: Cpp", &Style), ParseError::Success);
-
- CHECK_PARSE("---\n"
- "IndentWidth: 4\n"
- "---\n"
- "Language: Cpp\n"
- "IndentWidth: 8\n",
- IndentWidth, 8u);
-
- EXPECT_EQ(parseConfiguration("---\n"
- "Language: ObjC\n"
- "---\n"
- "Language: Cpp\n",
- &Style),
- ParseError::Success);
-}
-
-TEST(ConfigParseTest, HandleDotHFile) {
- FormatStyle Style = {};
- Style.Language = FormatStyle::LK_Cpp;
- EXPECT_EQ(parseConfiguration("Language: C", &Style,
- /*AllowUnknownOptions=*/false,
- /*IsDotHFile=*/true),
- ParseError::Success);
- EXPECT_EQ(Style.Language, FormatStyle::LK_C);
-
- Style = {};
- Style.Language = FormatStyle::LK_Cpp;
- EXPECT_EQ(parseConfiguration("Language: Cpp\n"
- "...\n"
- "Language: C",
- &Style,
- /*AllowUnknownOptions=*/false,
- /*IsDotHFile=*/true),
- ParseError::Success);
- EXPECT_EQ(Style.Language, FormatStyle::LK_Cpp);
-}
-
-TEST(ConfigParseTest, UsesLanguageForBasedOnStyle) {
- FormatStyle Style = {};
- Style.Language = FormatStyle::LK_JavaScript;
- Style.BreakBeforeTernaryOperators = true;
- EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Style).value());
- EXPECT_FALSE(Style.BreakBeforeTernaryOperators);
-
- Style.BreakBeforeTernaryOperators = true;
- EXPECT_EQ(0, parseConfiguration("---\n"
- "BasedOnStyle: Google\n"
- "---\n"
- "Language: JavaScript\n"
- "IndentWidth: 76\n"
- "...\n",
- &Style)
- .value());
- EXPECT_FALSE(Style.BreakBeforeTernaryOperators);
- EXPECT_EQ(76u, Style.IndentWidth);
- EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
+TEST_F(DefinitionBlockSeparatorTest, Always) {
+ FormatStyle Style = getLLVMStyle();
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+
+ verifyFormat("// clang-format off\n"
+ "template<class T>\n"
+ "concept C = not A<S<T>>;\n"
+ "// clang-format on\n"
+ "\n"
+ "struct E {};",
+ Style);
+
+ std::string Prefix = "namespace {\n";
+ std::string Infix = "\n"
+ "// Enum test1\n"
+ "// Enum test2\n"
+ "enum Foo { FOO, BAR };\n"
+ "\n"
+ "/*\n"
+ "test1\n"
+ "test2\n"
+ "*/\n"
+ "/*const*/ int foo(int i, int j) {\n"
+ " int r = i + j;\n"
+ " return r;\n"
+ "}\n"
+ "\n"
+ "// Foobar\n"
+ "int i, j, k;\n"
+ "\n"
+ "// Comment for function\n"
+ "// Comment line 2\n"
+ "// Comment line 3\n"
+ "int bar(int j, int k) {\n"
+ " {\n"
+ " int r = j * k;\n"
+ " return r;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "int bar2(int j, int k) {\n"
+ " int r = j / k;\n"
+ " return r;\n"
+ "}\n"
+ "\n"
+ "/* Comment block in one line*/\n"
+ "enum Bar { FOOBAR, BARFOO };\n"
+ "\n"
+ "int bar3(int j, int k, const enum Bar b) {\n"
+ " // A comment\n"
+ " int r = j % k;\n"
+ " if (struct S = getS()) {\n"
+ " // if condition\n"
+ " }\n"
+ " return r;\n"
+ "}\n";
+ std::string Postfix = "\n"
+ "} // namespace\n"
+ "\n"
+ "namespace T {\n"
+ "int i, j, k;\n"
+ "} // namespace T";
+ verifyFormat(Prefix + removeEmptyLines(Infix) + removeEmptyLines(Postfix),
+ Style, Prefix + Infix + Postfix);
}
-TEST(ConfigParseTest, ConfigurationRoundTripTest) {
+TEST_F(DefinitionBlockSeparatorTest, Never) {
FormatStyle Style = getLLVMStyle();
- std::string YAML = configurationAsText(Style);
- FormatStyle ParsedStyle = {};
- ParsedStyle.Language = FormatStyle::LK_Cpp;
- EXPECT_EQ(0, parseConfiguration(YAML, &ParsedStyle).value());
- EXPECT_EQ(Style, ParsedStyle);
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
+ std::string Prefix = "namespace {\n";
+ std::string Postfix = "// Enum test1\n"
+ "// Enum test2\n"
+ "enum Foo { FOO, BAR };\n"
+ "\n"
+ "/*\n"
+ "test1\n"
+ "test2\n"
+ "*/\n"
+ "/*const*/ int foo(int i, int j) {\n"
+ " int r = i + j;\n"
+ " return r;\n"
+ "}\n"
+ "\n"
+ "// Foobar\n"
+ "int i, j, k;\n"
+ "\n"
+ "// Comment for function\n"
+ "// Comment line 2\n"
+ "// Comment line 3\n"
+ "int bar(int j, int k) {\n"
+ " {\n"
+ " int r = j * k;\n"
+ " return r;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "int bar2(int j, int k) {\n"
+ " int r = j / k;\n"
+ " return r;\n"
+ "}\n"
+ "\n"
+ "/* Comment block in one line*/\n"
+ "enum Bar { FOOBAR, BARFOO };\n"
+ "\n"
+ "int bar3(int j, int k, const enum Bar b) {\n"
+ " // A comment\n"
+ " int r = j % k;\n"
+ " if (struct S = getS()) {\n"
+ " // if condition\n"
+ " }\n"
+ " return r;\n"
+ "}\n"
+ "} // namespace";
+ verifyFormat(Prefix + "\n\n\n" + Postfix, Style,
+ Prefix + removeEmptyLines(Postfix));
}
-TEST(ConfigParseTest, GetStyleWithEmptyFileName) {
- llvm::vfs::InMemoryFileSystem FS;
- auto Style1 = getStyle("file", "", "Google", "", &FS);
- ASSERT_TRUE((bool)Style1);
- ASSERT_EQ(*Style1, getGoogleStyle());
+TEST_F(DefinitionBlockSeparatorTest, OpeningBracketOwnsLine) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+ verifyFormat("namespace NS\n"
+ "{\n"
+ "// Enum test1\n"
+ "// Enum test2\n"
+ "enum Foo\n"
+ "{\n"
+ " FOO,\n"
+ " BAR\n"
+ "};\n"
+ "\n"
+ "/*\n"
+ "test1\n"
+ "test2\n"
+ "*/\n"
+ "/*const*/ int foo(int i, int j)\n"
+ "{\n"
+ " int r = i + j;\n"
+ " return r;\n"
+ "}\n"
+ "\n"
+ "// Foobar\n"
+ "int i, j, k;\n"
+ "\n"
+ "// Comment for function\n"
+ "// Comment line 2\n"
+ "// Comment line 3\n"
+ "int bar(int j, int k)\n"
+ "{\n"
+ " {\n"
+ " int r = j * k;\n"
+ " return r;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "int bar2(int j, int k)\n"
+ "{\n"
+ " int r = j / k;\n"
+ " return r;\n"
+ "}\n"
+ "\n"
+ "enum Bar\n"
+ "{\n"
+ " FOOBAR,\n"
+ " BARFOO\n"
+ "};\n"
+ "\n"
+ "int bar3(int j, int k, const enum Bar b)\n"
+ "{\n"
+ " // A comment\n"
+ " int r = j % k;\n"
+ " if (struct S = getS())\n"
+ " {\n"
+ " // if condition\n"
+ " }\n"
+ " return r;\n"
+ "}\n"
+ "} // namespace NS",
+ Style);
}
-TEST(ConfigParseTest, GetStyleOfFile) {
- llvm::vfs::InMemoryFileSystem FS;
- // Test 1: format file in the same directory.
- ASSERT_TRUE(
- FS.addFile("/a/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
- ASSERT_TRUE(
- FS.addFile("/a/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
- auto Style1 = getStyle("file", "/a/.clang-format", "Google", "", &FS);
- ASSERT_TRUE((bool)Style1);
- ASSERT_EQ(*Style1, getLLVMStyle());
-
- // Test 2.1: fallback to default.
- ASSERT_TRUE(
- FS.addFile("/b/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
- auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", "", &FS);
- ASSERT_TRUE((bool)Style2);
- ASSERT_EQ(*Style2, getMozillaStyle());
-
- // Test 2.2: no format on 'none' fallback style.
- Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS);
- ASSERT_TRUE((bool)Style2);
- ASSERT_EQ(*Style2, getNoStyle());
-
- // Test 2.3: format if config is found with no based style while fallback is
- // 'none'.
- ASSERT_TRUE(FS.addFile("/b/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("IndentWidth: 2")));
- Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS);
- ASSERT_TRUE((bool)Style2);
- ASSERT_EQ(*Style2, getLLVMStyle());
-
- // Test 2.4: format if yaml with no based style, while fallback is 'none'.
- Style2 = getStyle("{}", "a.h", "none", "", &FS);
- ASSERT_TRUE((bool)Style2);
- ASSERT_EQ(*Style2, getLLVMStyle());
-
- // Test 3: format file in parent directory.
- ASSERT_TRUE(
- FS.addFile("/c/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
- ASSERT_TRUE(FS.addFile("/c/sub/sub/sub/test.cpp", 0,
- llvm::MemoryBuffer::getMemBuffer("int i;")));
- auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", "", &FS);
- ASSERT_TRUE((bool)Style3);
- ASSERT_EQ(*Style3, getGoogleStyle());
-
- // Test 4: error on invalid fallback style
- auto Style4 = getStyle("file", "a.h", "KungFu", "", &FS);
- ASSERT_FALSE((bool)Style4);
- llvm::consumeError(Style4.takeError());
-
- // Test 5: error on invalid yaml on command line
- auto Style5 = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
- /*AllowUnknownOptions=*/false, dropDiagnosticHandler);
- ASSERT_FALSE((bool)Style5);
- llvm::consumeError(Style5.takeError());
-
- // Test 6: error on invalid style
- auto Style6 = getStyle("KungFu", "a.h", "LLVM", "", &FS);
- ASSERT_FALSE((bool)Style6);
- llvm::consumeError(Style6.takeError());
-
- // Test 7: found config file, error on parsing it
- ASSERT_TRUE(
- FS.addFile("/d/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM\n"
- "InvalidKey: InvalidValue")));
- ASSERT_TRUE(
- FS.addFile("/d/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
- auto Style7a = getStyle("file", "/d/.clang-format", "LLVM", "", &FS,
- /*AllowUnknownOptions=*/false, dropDiagnosticHandler);
- ASSERT_FALSE((bool)Style7a);
- llvm::consumeError(Style7a.takeError());
-
- auto Style7b = getStyle("file", "/d/.clang-format", "LLVM", "", &FS,
- /*AllowUnknownOptions=*/true, dropDiagnosticHandler);
- ASSERT_TRUE((bool)Style7b);
-
- // Test 8: inferred per-language defaults apply.
- auto StyleTd = getStyle("file", "x.td", "llvm", "", &FS);
- ASSERT_TRUE((bool)StyleTd);
- ASSERT_EQ(*StyleTd, getLLVMStyle(FormatStyle::LK_TableGen));
-
- // Test 9.1.1: overwriting a file style, when no parent file exists with no
- // fallback style.
- ASSERT_TRUE(FS.addFile(
- "/e/sub/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: InheritParentConfig\n"
- "ColumnLimit: 20")));
- ASSERT_TRUE(FS.addFile("/e/sub/code.cpp", 0,
- llvm::MemoryBuffer::getMemBuffer("int i;")));
- auto Style9 = getStyle("file", "/e/sub/code.cpp", "none", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, [] {
- auto Style = getNoStyle();
- Style.ColumnLimit = 20;
- return Style;
- }());
-
- // Test 9.1.2: propagate more than one level with no parent file.
- ASSERT_TRUE(FS.addFile("/e/sub/sub/code.cpp", 0,
- llvm::MemoryBuffer::getMemBuffer("int i;")));
- ASSERT_TRUE(FS.addFile("/e/sub/sub/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer(
- "BasedOnStyle: InheritParentConfig\n"
- "WhitespaceSensitiveMacros: ['FOO', 'BAR']")));
- std::vector<std::string> NonDefaultWhiteSpaceMacros =
- Style9->WhitespaceSensitiveMacros;
- NonDefaultWhiteSpaceMacros[0] = "FOO";
- NonDefaultWhiteSpaceMacros[1] = "BAR";
-
- ASSERT_NE(Style9->WhitespaceSensitiveMacros, NonDefaultWhiteSpaceMacros);
- Style9 = getStyle("file", "/e/sub/sub/code.cpp", "none", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, [&NonDefaultWhiteSpaceMacros] {
- auto Style = getNoStyle();
- Style.ColumnLimit = 20;
- Style.WhitespaceSensitiveMacros = NonDefaultWhiteSpaceMacros;
- return Style;
- }());
-
- // Test 9.2: with LLVM fallback style
- Style9 = getStyle("file", "/e/sub/code.cpp", "LLVM", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, [] {
- auto Style = getLLVMStyle();
- Style.ColumnLimit = 20;
- return Style;
- }());
-
- // Test 9.3: with a parent file
- ASSERT_TRUE(
- FS.addFile("/e/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google\n"
- "UseTab: Always")));
- Style9 = getStyle("file", "/e/sub/code.cpp", "none", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, [] {
- auto Style = getGoogleStyle();
- Style.ColumnLimit = 20;
- Style.UseTab = FormatStyle::UT_Always;
- return Style;
- }());
-
- // Test 9.4: propagate more than one level with a parent file.
- const auto SubSubStyle = [&NonDefaultWhiteSpaceMacros] {
- auto Style = getGoogleStyle();
- Style.ColumnLimit = 20;
- Style.UseTab = FormatStyle::UT_Always;
- Style.WhitespaceSensitiveMacros = NonDefaultWhiteSpaceMacros;
- return Style;
- }();
-
- ASSERT_NE(Style9->WhitespaceSensitiveMacros, NonDefaultWhiteSpaceMacros);
- Style9 = getStyle("file", "/e/sub/sub/code.cpp", "none", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, SubSubStyle);
-
- // Test 9.5: use InheritParentConfig as style name
- Style9 =
- getStyle("inheritparentconfig", "/e/sub/sub/code.cpp", "none", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, SubSubStyle);
-
- // Test 9.6: use command line style with inheritance
- Style9 = getStyle("{BasedOnStyle: InheritParentConfig}",
- "/e/sub/sub/code.cpp", "none", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, SubSubStyle);
-
- // Test 9.7: use command line style with inheritance and own config
- Style9 = getStyle("{BasedOnStyle: InheritParentConfig, "
- "WhitespaceSensitiveMacros: ['FOO', 'BAR']}",
- "/e/sub/code.cpp", "none", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, SubSubStyle);
-
- // Test 9.8: use inheritance from a file without BasedOnStyle
- ASSERT_TRUE(FS.addFile(
- "/e/withoutbase/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BracedInitializerIndentWidth: 2\n"
- "ColumnLimit: 123")));
- ASSERT_TRUE(
- FS.addFile("/e/withoutbase/sub/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer(
- "BasedOnStyle: InheritParentConfig\nIndentWidth: 7")));
- // Make sure we do not use the fallback style
- Style9 = getStyle("file", "/e/withoutbase/code.cpp", "google", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, [] {
- auto Style = getLLVMStyle();
- Style.BracedInitializerIndentWidth = 2;
- Style.ColumnLimit = 123;
- return Style;
- }());
-
- Style9 = getStyle("file", "/e/withoutbase/sub/code.cpp", "google", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, [] {
- auto Style = getLLVMStyle();
- Style.BracedInitializerIndentWidth = 2;
- Style.ColumnLimit = 123;
- Style.IndentWidth = 7;
- return Style;
- }());
-
- // Test 9.9: use inheritance from a specific config file.
- Style9 = getStyle("file:/e/sub/sub/.clang-format", "/e/sub/sub/code.cpp",
- "none", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style9));
- ASSERT_EQ(*Style9, SubSubStyle);
+TEST_F(DefinitionBlockSeparatorTest, TryBlocks) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+ verifyFormat("void FunctionWithInternalTry()\n"
+ "{\n"
+ " try\n"
+ " {\n"
+ " return;\n"
+ " }\n"
+ " catch (const std::exception &)\n"
+ " {\n"
+ " }\n"
+ "}",
+ Style, "", /*Inverse=*/false);
+ verifyFormat("void FunctionWithTryBlock()\n"
+ "try\n"
+ "{\n"
+ " return;\n"
+ "}\n"
+ "catch (const std::exception &)\n"
+ "{\n"
+ "}",
+ Style, "", /*Inverse=*/false);
}
-TEST(ConfigParseTest, GetStyleOfSpecificFile) {
- llvm::vfs::InMemoryFileSystem FS;
- // Specify absolute path to a format file in a parent directory.
- ASSERT_TRUE(
- FS.addFile("/e/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
- ASSERT_TRUE(
- FS.addFile("/e/explicit.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
- ASSERT_TRUE(FS.addFile("/e/sub/sub/sub/test.cpp", 0,
- llvm::MemoryBuffer::getMemBuffer("int i;")));
- auto Style = getStyle("file:/e/explicit.clang-format",
- "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style));
- ASSERT_EQ(*Style, getGoogleStyle());
-
- // Specify relative path to a format file.
- ASSERT_TRUE(
- FS.addFile("../../e/explicit.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
- Style = getStyle("file:../../e/explicit.clang-format",
- "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style));
- ASSERT_EQ(*Style, getGoogleStyle());
-
- // Specify path to a format file that does not exist.
- Style = getStyle("file:/e/missing.clang-format", "/e/sub/sub/sub/test.cpp",
- "LLVM", "", &FS);
- ASSERT_FALSE(static_cast<bool>(Style));
- llvm::consumeError(Style.takeError());
-
- // Specify path to a file on the filesystem.
- SmallString<128> FormatFilePath;
- std::error_code ECF = llvm::sys::fs::createTemporaryFile(
- "FormatFileTest", "tpl", FormatFilePath);
- EXPECT_FALSE((bool)ECF);
- llvm::raw_fd_ostream FormatFileTest(FormatFilePath, ECF);
- EXPECT_FALSE((bool)ECF);
- FormatFileTest << "BasedOnStyle: Google\n";
- FormatFileTest.close();
-
- SmallString<128> TestFilePath;
- std::error_code ECT =
- llvm::sys::fs::createTemporaryFile("CodeFileTest", "cc", TestFilePath);
- EXPECT_FALSE((bool)ECT);
- llvm::raw_fd_ostream CodeFileTest(TestFilePath, ECT);
- CodeFileTest << "int i;\n";
- CodeFileTest.close();
-
- std::string format_file_arg = std::string("file:") + FormatFilePath.c_str();
- Style = getStyle(format_file_arg, TestFilePath, "LLVM", "", nullptr);
-
- llvm::sys::fs::remove(FormatFilePath.c_str());
- llvm::sys::fs::remove(TestFilePath.c_str());
- ASSERT_TRUE(static_cast<bool>(Style));
- ASSERT_EQ(*Style, getGoogleStyle());
+TEST_F(DefinitionBlockSeparatorTest, Leave) {
+ FormatStyle Style = getLLVMStyle();
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Leave;
+ Style.MaxEmptyLinesToKeep = 3;
+ std::string LeaveAs = "namespace {\n"
+ "\n"
+ "// Enum test1\n"
+ "// Enum test2\n"
+ "enum Foo { FOO, BAR };\n"
+ "\n\n\n"
+ "/*\n"
+ "test1\n"
+ "test2\n"
+ "*/\n"
+ "/*const*/ int foo(int i, int j) {\n"
+ " int r = i + j;\n"
+ " return r;\n"
+ "}\n"
+ "\n"
+ "// Foobar\n"
+ "int i, j, k;\n"
+ "\n"
+ "// Comment for function\n"
+ "// Comment line 2\n"
+ "// Comment line 3\n"
+ "int bar(int j, int k) {\n"
+ " {\n"
+ " int r = j * k;\n"
+ " return r;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "int bar2(int j, int k) {\n"
+ " int r = j / k;\n"
+ " return r;\n"
+ "}\n"
+ "\n"
+ "// Comment for inline enum\n"
+ "enum Bar { FOOBAR, BARFOO };\n"
+ "int bar3(int j, int k, const enum Bar b) {\n"
+ " // A comment\n"
+ " int r = j % k;\n"
+ " if (struct S = getS()) {\n"
+ " // if condition\n"
+ " }\n"
+ " return r;\n"
+ "}\n"
+ "} // namespace";
+ verifyFormat(LeaveAs, Style, LeaveAs);
}
-TEST(ConfigParseTest, GetStyleOutput) {
- llvm::vfs::InMemoryFileSystem FS;
-
- // Don't suppress output.
- testing::internal::CaptureStderr();
- auto Style = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
- /*AllowUnknownOptions=*/true);
- auto Output = testing::internal::GetCapturedStderr();
- ASSERT_TRUE((bool)Style);
- ASSERT_FALSE(Output.empty());
-
- // Suppress stderr.
- testing::internal::CaptureStderr();
- Style = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS,
- /*AllowUnknownOptions=*/true, dropDiagnosticHandler);
- Output = testing::internal::GetCapturedStderr();
- ASSERT_TRUE((bool)Style);
- ASSERT_TRUE(Output.empty());
+TEST_F(DefinitionBlockSeparatorTest, CSharp) {
+ FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
+ Style.AllowShortEnumsOnASingleLine = false;
+ verifyFormat("namespace {\r\n"
+ "public class SomeTinyClass {\r\n"
+ " int X;\r\n"
+ "}\r\n"
+ "\r\n"
+ "public class AnotherTinyClass {\r\n"
+ " int Y;\r\n"
+ "}\r\n"
+ "\r\n"
+ "internal static String toString() {\r\n"
+ "}\r\n"
+ "\r\n"
+ "// Comment for enum\r\n"
+ "public enum var {\r\n"
+ " none,\r\n"
+ " @string,\r\n"
+ " bool,\r\n"
+ " @enum\r\n"
+ "}\r\n"
+ "\r\n"
+ "// Test\r\n"
+ "[STAThread]\r\n"
+ "static void Main(string[] args) {\r\n"
+ " Console.WriteLine(\"HelloWorld\");\r\n"
+ "}\r\n"
+ "\r\n"
+ "static decimal Test() {\r\n"
+ "}\r\n"
+ "}\r\n"
+ "\r\n"
+ "public class FoobarClass {\r\n"
+ " int foobar;\r\n"
+ "}\r\n"
+ "\r\n"
+ "public class LogFactory<TLogger>\r\n"
+ " where TLogger : class, new() {\r\n"
+ " int i;\r\n"
+ "}",
+ Style);
}
-TEST(ConfigParseTest, RedirectInheritance) {
- llvm::vfs::InMemoryFileSystem FS;
- constexpr StringRef Config("BasedOnStyle: InheritParentConfig\n"
- "ColumnLimit: 20");
- constexpr StringRef Code("int *f(int i, int j);");
-
- ASSERT_TRUE(
- FS.addFile("/a/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: GNU")));
- ASSERT_TRUE(FS.addFile("/a/proj/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer(
- "BasedOnStyle: InheritParentConfig=/a/config")));
- ASSERT_TRUE(
- FS.addFile("/a/proj/test.cc", 0, llvm::MemoryBuffer::getMemBuffer(Code)));
- auto Style = getStyle("file", "/a/proj/test.cc", "none", "", &FS);
- ASSERT_FALSE(static_cast<bool>(Style));
- ASSERT_EQ(toString(Style.takeError()),
- "Failed to inherit configuration directory /a/config");
-
- ASSERT_TRUE(FS.addFile("/a/config/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer(Config)));
- Style = getStyle("file", "/a/proj/test.cc", "none", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style));
- ASSERT_EQ(*Style, [] {
- auto Style = getGNUStyle();
- Style.ColumnLimit = 20;
- return Style;
- }());
-
- ASSERT_TRUE(FS.addFile(
- "/a/proj/src/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: InheritParentConfig\n"
- "PointerAlignment: Left")));
- ASSERT_TRUE(FS.addFile("/a/proj/src/test.cc", 0,
- llvm::MemoryBuffer::getMemBuffer(Code)));
- Style = getStyle("file", "/a/proj/src/test.cc", "none", "", &FS);
- ASSERT_TRUE(static_cast<bool>(Style));
- ASSERT_EQ(*Style, [] {
- auto Style = getGNUStyle();
- Style.ColumnLimit = 20;
- Style.PointerAlignment = FormatStyle::PAS_Left;
- return Style;
- }());
-
- ASSERT_TRUE(FS.addFile("/a/loop/.clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer(
- "BasedOnStyle: InheritParentConfig=config/")));
- ASSERT_TRUE(
- FS.addFile("/a/loop/test.cc", 0, llvm::MemoryBuffer::getMemBuffer(Code)));
- ASSERT_TRUE(FS.addFile("/a/loop/config/_clang-format", 0,
- llvm::MemoryBuffer::getMemBuffer(Config)));
- Style = getStyle("file", "/a/loop/test.cc", "none", "", &FS);
- ASSERT_FALSE(static_cast<bool>(Style));
- ASSERT_EQ(toString(Style.takeError()),
- "Loop detected when inheriting configuration file in /a/loop");
+TEST_F(DefinitionBlockSeparatorTest, JavaScript) {
+ FormatStyle Style = getLLVMStyle(FormatStyle::LK_JavaScript);
+ Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
+ Style.AllowShortEnumsOnASingleLine = false;
+ verifyFormat("export const enum Foo {\n"
+ " A = 1,\n"
+ " B\n"
+ "}\n"
+ "\n"
+ "export function A() {\n"
+ "}\n"
+ "\n"
+ "export default function B() {\n"
+ "}\n"
+ "\n"
+ "export function C() {\n"
+ "}\n"
+ "\n"
+ "var t, p, q;\n"
+ "\n"
+ "export abstract class X {\n"
+ " y: number;\n"
+ "}\n"
+ "\n"
+ "export const enum Bar {\n"
+ " D = 1,\n"
+ " E\n"
+ "}",
+ Style);
}
-
} // namespace
} // namespace format
} // namespace clang
>From 04516b171fec8003840297bc542662a719379cd4 Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 14 Mar 2026 20:10:13 -0700
Subject: [PATCH 17/17] Refactor AllowShortFunctionsOnASingleLine style usage
---
clang/unittests/Format/FormatTest.cpp | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index a1788a7a2b483..8d52e1a3b963f 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -3522,7 +3522,7 @@ TEST_F(FormatTest, MultiLineControlStatements) {
verifyFormat("struct T shortfunction() { return bar(); }", Style);
verifyFormat("struct T {};", Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
verifyFormat("void shortfunction()\n"
"{\n"
" bar();\n"
@@ -3546,7 +3546,7 @@ TEST_F(FormatTest, MultiLineControlStatements) {
"};",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
verifyFormat("void shortfunction() {\n"
" bar();\n"
"}",
@@ -8513,7 +8513,7 @@ TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
"};",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
verifyNoChange("SomeClass::Constructor() :\n"
" a(a), b(b), c(c) {\n"
"}",
@@ -12619,7 +12619,7 @@ TEST_F(FormatTest, UnderstandsAttributes) {
// Check that these are not parsed as function declarations:
CustomAttrs.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({});
+ FormatStyle::ShortFunctionStyle();
CustomAttrs.BreakBeforeBraces = FormatStyle::BS_Allman;
verifyFormat("SomeType s(InitValue);", CustomAttrs);
verifyFormat("SomeType s{InitValue};", CustomAttrs);
@@ -12728,7 +12728,7 @@ TEST_F(FormatTest, UnderstandsSquareAttributes) {
// Make sure we do not parse attributes as lambda introducers.
FormatStyle MultiLineFunctions = getLLVMStyle();
MultiLineFunctions.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({});
+ FormatStyle::ShortFunctionStyle();
verifyFormat("[[unused]] int b() {\n"
" return 42;\n"
"}",
@@ -14833,7 +14833,7 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) {
TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
FormatStyle DoNotMerge = getLLVMStyle();
DoNotMerge.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({});
+ FormatStyle::ShortFunctionStyle();
verifyFormat("void f() { return 42; }");
verifyFormat("void f() {\n"
@@ -14904,7 +14904,7 @@ TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
FormatStyle DoNotMergeNoColumnLimit = NoColumnLimit;
DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine =
- FormatStyle::ShortFunctionStyle({});
+ FormatStyle::ShortFunctionStyle();
verifyFormat("A() : b(0) {\n"
"}",
DoNotMergeNoColumnLimit);
@@ -15253,7 +15253,7 @@ TEST_F(FormatTest, PullInlineOnlyFunctionDefinitionsIntoSingleLine) {
TEST_F(FormatTest, SplitEmptyFunction) {
FormatStyle Style = getLLVMStyleWithColumns(40);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
Style.BraceWrapping.AfterFunction = true;
Style.BraceWrapping.SplitEmptyFunction = false;
@@ -15327,7 +15327,7 @@ TEST_F(FormatTest, SplitEmptyFunction) {
TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
FormatStyle Style = getLLVMStyleWithColumns(40);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
Style.BraceWrapping.AfterFunction = true;
Style.BraceWrapping.SplitEmptyFunction = true;
@@ -15357,7 +15357,7 @@ TEST_F(FormatTest, SplitEmptyFunctionButNotRecord) {
TEST_F(FormatTest, MergeShortFunctionBody) {
auto Style = getLLVMStyle();
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always;
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
Style.BraceWrapping.AfterFunction = true;
@@ -23346,7 +23346,7 @@ TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
"}",
Style);
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
verifyFormat("SomeClass::Constructor()\n"
" : a(a)\n"
" , b(b)\n"
@@ -27719,7 +27719,7 @@ TEST_F(FormatTest, FormatDecayCopy) {
TEST_F(FormatTest, Cpp20ModulesSupport) {
FormatStyle Style = getLLVMStyle();
Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
- Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle({});
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
verifyFormat("export import foo;", Style);
verifyFormat("export import foo:bar;", Style);
More information about the cfe-commits
mailing list