Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -1042,6 +1042,18 @@ +.. _AllowShortCSharpPropertiesOnASingleLine: + +**AllowShortCSharpPropertiesOnASingleLine** (``Boolean``) :versionbadge:`clang-format 17.0` :ref:`¶ ` + If ``true``, short CSharp properties will be contracted to a single line. + + .. code-block:: c++ + + true: false: + public string Foo { set; get; } public string Foo { + set; get; + } + .. _AllowShortCaseLabelsOnASingleLine: **AllowShortCaseLabelsOnASingleLine** (``Boolean``) :versionbadge:`clang-format 3.6` :ref:`¶ ` @@ -1385,6 +1397,19 @@ "bbbb" "cccc"; "cccc"; +.. _AlwaysBreakBetweenShortCSharpProperties: + +**AlwaysBreakBetweenShortCSharpProperties** (``Boolean``) :versionbadge:`clang-format 17.0` :ref:`¶ ` + If ``true``, short CSharp properties will be contracted to a single line. + + .. code-block:: c++ + + true: false: + public string Foo { public string Foo { + set; set; get; + get; } + } + .. _AlwaysBreakTemplateDeclarations: **AlwaysBreakTemplateDeclarations** (``BreakTemplateDeclarationsStyle``) :versionbadge:`clang-format 3.4` :ref:`¶ ` @@ -1628,6 +1653,32 @@ {} + * ``bool AfterCSharpProperty`` Wrap C# setter/getter properties. + + .. code-block:: c++ + + true: + string Foo { + get + { + return _foo; + } + set + { + _foo = value; + } + } + + false: + string Foo { + get { + return _foo; + } + set { + return _value + } + } + * ``bool AfterEnum`` Wrap enum definitions. .. code-block:: c++ Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -470,6 +470,12 @@ - Add additional Qualifier Ordering support for special cases such as templates, requires clauses, long qualified names. - Fix all known issues associated with ``LambdaBodyIndentation: OuterScope``. +- Add ``AfterCSharpProperty`` style to option ``BraceWrapping`` to allow + newline before the opening brace of ``set;get;``. +- Add ``AllowShortCSharpPropertiesOnASingleLine`` style to allow C# properties + To be on a single line. +- Add ``AlwaysBreakBetweenShortCSharpProperties`` style to allow C# auto + properties to be split across multiple lines. libclang -------- Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -538,6 +538,16 @@ /// \version 3.6 bool AllowShortCaseLabelsOnASingleLine; + /// If ``true``, short CSharp properties will be contracted to a single line. + /// \code + /// true: false: + /// public string Foo { set; get; } public string Foo { + /// set; get; + /// } + /// \endcode + /// \version 17.0 + bool AllowShortCSharpPropertiesOnASingleLine; + /// Allow short enums on a single line. /// \code /// true: @@ -858,6 +868,17 @@ BTDS_Yes }; + /// If ``true``, short CSharp properties will be contracted to a single line. + /// \code + /// true: false: + /// public string Foo { public string Foo { + /// set; set; get; + /// get; } + /// } + /// \endcode + /// \version 17.0 + bool AlwaysBreakBetweenShortCSharpProperties; + /// The template declaration breaking style to use. /// \version 3.4 BreakTemplateDeclarationsStyle AlwaysBreakTemplateDeclarations; @@ -1002,6 +1023,7 @@ /// } /// \endcode bool AfterCaseLabel; + /// Wrap class definitions. /// \code /// true: @@ -1015,6 +1037,33 @@ /// Wrap control statements (``if``/``for``/``while``/``switch``/..). BraceWrappingAfterControlStatementStyle AfterControlStatement; + + /// Wrap C# setter/getter properties. + /// \code + /// true: + /// string Foo { + /// get + /// { + /// return _foo; + /// } + /// set + /// { + /// _foo = value; + /// } + /// } + /// + /// false: + /// string Foo { + /// get { + /// return _foo; + /// } + /// set { + /// return _value + /// } + /// } + /// \endcode + bool AfterCSharpProperty; + /// Wrap enum definitions. /// \code /// true: @@ -1205,6 +1254,28 @@ /// \endcode /// bool SplitEmptyNamespace; + + bool operator==(const BraceWrappingFlags &Other) const { + return AfterCaseLabel == Other.AfterCaseLabel && + AfterClass == Other.AfterClass && + AfterControlStatement == Other.AfterControlStatement && + AfterCSharpProperty == Other.AfterCSharpProperty && + AfterEnum == Other.AfterEnum && + AfterFunction == Other.AfterFunction && + AfterNamespace == Other.AfterNamespace && + AfterObjCDeclaration == Other.AfterObjCDeclaration && + AfterStruct == Other.AfterStruct && + AfterUnion == Other.AfterUnion && + AfterExternBlock == Other.AfterExternBlock && + BeforeCatch == Other.BeforeCatch && + BeforeElse == Other.BeforeElse && + BeforeLambdaBody == Other.BeforeLambdaBody && + BeforeWhile == Other.BeforeWhile && + IndentBraces == Other.IndentBraces && + SplitEmptyFunction == Other.SplitEmptyFunction && + SplitEmptyRecord == Other.SplitEmptyRecord && + SplitEmptyNamespace == Other.SplitEmptyNamespace; + } }; /// Control of individual brace wrapping cases. @@ -4270,6 +4341,8 @@ AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine && AllowShortCaseLabelsOnASingleLine == R.AllowShortCaseLabelsOnASingleLine && + AllowShortCSharpPropertiesOnASingleLine == + R.AllowShortCSharpPropertiesOnASingleLine && AllowShortEnumsOnASingleLine == R.AllowShortEnumsOnASingleLine && AllowShortFunctionsOnASingleLine == R.AllowShortFunctionsOnASingleLine && @@ -4280,6 +4353,8 @@ AlwaysBreakAfterReturnType == R.AlwaysBreakAfterReturnType && AlwaysBreakBeforeMultilineStrings == R.AlwaysBreakBeforeMultilineStrings && + AlwaysBreakBetweenShortCSharpProperties == + R.AlwaysBreakBetweenShortCSharpProperties && AlwaysBreakTemplateDeclarations == R.AlwaysBreakTemplateDeclarations && AttributeMacros == R.AttributeMacros && Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -178,6 +178,7 @@ IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel); IO.mapOptional("AfterClass", Wrapping.AfterClass); IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement); + IO.mapOptional("AfterCSharpProperty", Wrapping.AfterCSharpProperty); IO.mapOptional("AfterEnum", Wrapping.AfterEnum); IO.mapOptional("AfterExternBlock", Wrapping.AfterExternBlock); IO.mapOptional("AfterFunction", Wrapping.AfterFunction); @@ -857,6 +858,8 @@ Style.AllowShortBlocksOnASingleLine); IO.mapOptional("AllowShortCaseLabelsOnASingleLine", Style.AllowShortCaseLabelsOnASingleLine); + IO.mapOptional("AllowShortCSharpPropertiesOnASingleLine", + Style.AllowShortCSharpPropertiesOnASingleLine); IO.mapOptional("AllowShortEnumsOnASingleLine", Style.AllowShortEnumsOnASingleLine); IO.mapOptional("AllowShortFunctionsOnASingleLine", @@ -873,6 +876,8 @@ Style.AlwaysBreakAfterReturnType); IO.mapOptional("AlwaysBreakBeforeMultilineStrings", Style.AlwaysBreakBeforeMultilineStrings); + IO.mapOptional("AlwaysBreakBetweenShortCSharpProperties", + Style.AlwaysBreakBetweenShortCSharpProperties); IO.mapOptional("AlwaysBreakTemplateDeclarations", Style.AlwaysBreakTemplateDeclarations); IO.mapOptional("AttributeMacros", Style.AttributeMacros); @@ -1174,6 +1179,7 @@ Expanded.BraceWrapping = {/*AfterCaseLabel=*/false, /*AfterClass=*/false, /*AfterControlStatement=*/FormatStyle::BWACS_Never, + /*AfterCSharpProperty=*/false, /*AfterEnum=*/false, /*AfterFunction=*/false, /*AfterNamespace=*/false, @@ -1247,6 +1253,7 @@ /*AfterCaseLabel=*/true, /*AfterClass=*/true, /*AfterControlStatement=*/FormatStyle::BWACS_Always, + /*AfterCSharpProperty=*/false, /*AfterEnum=*/true, /*AfterFunction=*/true, /*AfterNamespace=*/true, @@ -1324,6 +1331,7 @@ LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; LLVMStyle.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; LLVMStyle.AllowShortCaseLabelsOnASingleLine = false; + LLVMStyle.AllowShortCSharpPropertiesOnASingleLine = true; LLVMStyle.AllowShortEnumsOnASingleLine = true; LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never; @@ -1332,29 +1340,33 @@ LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None; LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None; LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; + LLVMStyle.AlwaysBreakBetweenShortCSharpProperties = false; LLVMStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_MultiLine; LLVMStyle.AttributeMacros.push_back("__capability"); LLVMStyle.BitFieldColonSpacing = FormatStyle::BFCS_Both; LLVMStyle.BinPackArguments = true; LLVMStyle.BinPackParameters = true; - LLVMStyle.BraceWrapping = {/*AfterCaseLabel=*/false, - /*AfterClass=*/false, - /*AfterControlStatement=*/FormatStyle::BWACS_Never, - /*AfterEnum=*/false, - /*AfterFunction=*/false, - /*AfterNamespace=*/false, - /*AfterObjCDeclaration=*/false, - /*AfterStruct=*/false, - /*AfterUnion=*/false, - /*AfterExternBlock=*/false, - /*BeforeCatch=*/false, - /*BeforeElse=*/false, - /*BeforeLambdaBody=*/false, - /*BeforeWhile=*/false, - /*IndentBraces=*/false, - /*SplitEmptyFunction=*/true, - /*SplitEmptyRecord=*/true, - /*SplitEmptyNamespace=*/true}; + LLVMStyle.BraceWrapping = { + /*AfterCaseLabel=*/false, + /*AfterClass=*/false, + /*AfterControlStatement=*/FormatStyle::BWACS_Never, + /*AfterCSharpProperty=*/false, + /*AfterEnum=*/false, + /*AfterFunction=*/false, + /*AfterNamespace=*/false, + /*AfterObjCDeclaration=*/false, + /*AfterStruct=*/false, + /*AfterUnion=*/false, + /*AfterExternBlock=*/false, + /*BeforeCatch=*/false, + /*BeforeElse=*/false, + /*BeforeLambdaBody=*/false, + /*BeforeWhile=*/false, + /*IndentBraces=*/false, + /*SplitEmptyFunction=*/true, + /*SplitEmptyRecord=*/true, + /*SplitEmptyNamespace=*/true, + }; LLVMStyle.BreakAfterAttributes = FormatStyle::ABS_Never; LLVMStyle.BreakAfterJavaFieldAnnotations = false; LLVMStyle.BreakArrays = true; Index: clang/lib/Format/TokenAnnotator.h =================================================================== --- clang/lib/Format/TokenAnnotator.h +++ clang/lib/Format/TokenAnnotator.h @@ -241,6 +241,14 @@ FormatStyle::PointerAlignmentStyle getTokenPointerOrReferenceAlignment( const FormatToken &PointerOrReference) const; + // Convienience Function for C# properties. + bool isCSharpProperty(const FormatToken &Tok) const; + bool isCSharpProperty(const FormatToken *Tok) const; + + // Convienience Function for C# accessor. + bool isCSharpAccessor(const FormatToken &Tok) const; + bool isCSharpAccessor(const FormatToken *Tok) const; + const FormatStyle &Style; const AdditionalKeywords &Keywords; Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -4714,6 +4714,22 @@ return Next; } +bool TokenAnnotator::isCSharpProperty(const FormatToken &Tok) const { + return Tok.isOneOf(Keywords.kw_get, Keywords.kw_set, Keywords.kw_init); +} + +bool TokenAnnotator::isCSharpProperty(const FormatToken *Tok) const { + return Tok && isCSharpProperty(*Tok); +} + +bool TokenAnnotator::isCSharpAccessor(const FormatToken &Tok) const { + return Tok.isOneOf(Keywords.kw_internal, tok::kw_public, tok::kw_private, + tok::kw_protected); +} +bool TokenAnnotator::isCSharpAccessor(const FormatToken *Tok) const { + return Tok && isCSharpAccessor(*Tok); +} + bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right) const { const FormatToken &Left = *Right.Previous; @@ -4986,10 +5002,7 @@ if (isAllmanBrace(Left) || isAllmanBrace(Right)) { auto FirstNonComment = getFirstNonComment(Line); - bool AccessSpecifier = - FirstNonComment && - FirstNonComment->isOneOf(Keywords.kw_internal, tok::kw_public, - tok::kw_private, tok::kw_protected); + bool AccessSpecifier = isCSharpAccessor(FirstNonComment); if (Style.BraceWrapping.AfterEnum) { if (Line.startsWith(tok::kw_enum) || @@ -5011,6 +5024,23 @@ return true; } + // We need to handle the '{' cases here. + // Handle `string Foo {{set {} get {}}`. + if (Style.isCSharp() && Style.BraceWrapping.AfterCSharpProperty) { + if (isCSharpProperty(Line.First)) + return true; + + // string Foo + // { + // set; internal get + // {} + // } + if (isCSharpProperty(Left) && Right.is(tok::l_brace) && + isCSharpAccessor(Left.Previous)) { + return true; + } + } + // Don't attempt to interpret struct return types as structs. if (Right.isNot(TT_FunctionLBrace)) { return (Line.startsWith(tok::kw_class) && @@ -5020,6 +5050,75 @@ } } + // The handling of C# properties and auto-properties. + if (Style.isCSharp()) { + // Handle default `string Foo {set;get }`. + if (Style.AlwaysBreakBetweenShortCSharpProperties && Left.is(tok::semi) && + isCSharpProperty(Right)) { + return true; + } + + // Handle non short property on a single line. + // string Foo { + // set;get; + // } + if (!Style.BraceWrapping.AfterFunction && + !Style.AllowShortCSharpPropertiesOnASingleLine) { + if (Left.is(tok::l_brace) && isCSharpProperty(Right)) + return true; + // string Foo { + // set;get; + // } + if (Left.is(tok::l_brace) && isCSharpAccessor(Right) && + isCSharpProperty(Right.Next)) { + return true; + } + if (Left.is(tok::semi) && Right.is(tok::r_brace) && + isCSharpProperty(Left.Previous)) { + return true; + } + } + + if (Style.BraceWrapping.AfterFunction && + !Style.AllowShortCSharpPropertiesOnASingleLine) { + // string Foo + // { + // set;get; + // } + if (Left.is(tok::l_brace) && isCSharpAccessor(Right) && + isCSharpProperty(Right.Next)) { + return true; + } + // string Foo + // { + // set; get; + // } + if (Left.is(tok::semi) && isCSharpAccessor(Right) && + isCSharpProperty(Right.Next)) { + return Style.AlwaysBreakBetweenShortCSharpProperties; + } + } + + // string Foo + // { + // set; get; + // } + if (Style.BraceWrapping.AfterCSharpProperty && Left.is(tok::l_brace) && + isCSharpProperty(Right)) { + return true; + } + + // string Foo + // { + // set; + // get; + // } + if (Style.BraceWrapping.AfterCSharpProperty && Left.is(tok::semi) && + Right.is(tok::r_brace)) { + return true; + } + } + if (Left.is(TT_ObjCBlockLBrace) && Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never) { return true; Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -2073,8 +2073,22 @@ // Try to parse the property accessor: // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties Tokens->setPosition(StoredPosition); - if (!IsTrivialPropertyAccessor && Style.BraceWrapping.AfterFunction) + if (!IsTrivialPropertyAccessor && + Style.AllowShortCSharpPropertiesOnASingleLine && + Style.BraceWrapping.AfterFunction) { addUnwrappedLine(); + } + + // Handle non short property on a single line + // string Foo + // { + // set;get; + // } + if (!Style.AllowShortCSharpPropertiesOnASingleLine && + Style.BraceWrapping.AfterFunction) { + addUnwrappedLine(); + } + nextToken(); do { switch (FormatTok->Tok.getKind()) { @@ -2087,6 +2101,16 @@ } addUnwrappedLine(); return true; + case tok::semi: + if (!IsTrivialPropertyAccessor) { + ++Line->Level; + nextToken(); + addUnwrappedLine(); + --Line->Level; + break; + } + nextToken(); + break; case tok::l_brace: ++Line->Level; parseBlock(/*MustBeDeclaration=*/true); @@ -2107,12 +2131,24 @@ nextToken(); break; default: - if (FormatTok->isOneOf(Keywords.kw_get, Keywords.kw_init, - Keywords.kw_set) && + bool WrappedAlready = false; + if (FormatTok->isOneOf(Keywords.kw_internal, tok::kw_private, + tok::kw_public, tok::kw_protected) && !IsTrivialPropertyAccessor) { // Non-trivial get/set needs to be on its own line. addUnwrappedLine(); + nextToken(); + WrappedAlready = true; } + if (FormatTok->isOneOf(Keywords.kw_get, Keywords.kw_init, Keywords.kw_set, + Keywords.kw_internal, tok::kw_private, + tok::kw_public, tok::kw_protected) && + !IsTrivialPropertyAccessor) { + // Non-trivial get/set needs to be on its own line. + if (!WrappedAlready) + addUnwrappedLine(); + } + nextToken(); } } while (!eof()); Index: clang/unittests/Format/FormatTestCSharp.cpp =================================================================== --- clang/unittests/Format/FormatTestCSharp.cpp +++ clang/unittests/Format/FormatTestCSharp.cpp @@ -42,14 +42,17 @@ return Style; } - static void verifyFormat( - llvm::StringRef Code, + static void _verifyFormat( + const char *File, int Line, llvm::StringRef Code, const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) { + ::testing::ScopedTrace t(File, Line, ::testing::Message() << Code.str()); EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable"; EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); } }; +#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__) + TEST_F(FormatTestCSharp, CSharpClass) { verifyFormat("public class SomeClass\n" "{\n" @@ -1612,5 +1615,424 @@ EXPECT_NE("", format("int where b <")); // reduced from crasher } +TEST_F(FormatTestCSharp, PropertyWrapping) { + FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); + + Style.BraceWrapping.AfterCSharpProperty = false; + Style.AllowShortCSharpPropertiesOnASingleLine = true; + Style.AlwaysBreakBetweenShortCSharpProperties = false; + Style.BraceWrapping.AfterFunction = true; + + verifyFormat("class A\n" + "{\n" + " string Foo { set; get; }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Foo { get; set; }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Foo { get; init; }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Foo\n" + " {\n" + " set {\n" + " val = value;\n" + " }\n" + " get {\n" + " return value;\n" + " }\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Foo\n" + " {\n" + " init {\n" + " val = value;\n" + " }\n" + " get {\n" + " return value;\n" + " }\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Foo\n" + " {\n" + " get;\n" + " set {\n" + " val = value;\n" + " }\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Foo\n" + " {\n" + " get;\n" + " init {\n" + " val = value;\n" + " }\n" + " }\n" + "}", + Style); + + verifyFormat("class A\n" + "{\n" + " string Foo { private set; get; }\n" + "}", + Style); + + verifyFormat("class A\n" + "{\n" + " string Foo { set; public get; }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Foo\n" + " {\n" + " get;\n" + " public init {\n" + " val = value;\n" + " }\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Foo\n" + " {\n" + " public init {\n" + " val = value;\n" + " }\n" + " get;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Foo\n" + " {\n" + " public get;\n" + " init {\n" + " val = value;\n" + " }\n" + " }\n" + "}", + Style); + + verifyFormat("class A\n" + "{\n" + " string Foo\n" + " {\n" + " get;\n" + " public init {\n" + " val = value;\n" + " }\n" + " }\n" + "}", + Style); + + Style.BraceWrapping.AfterCSharpProperty = true; + Style.AllowShortCSharpPropertiesOnASingleLine = false; + Style.AlwaysBreakBetweenShortCSharpProperties = true; + Style.BraceWrapping.AfterFunction = true; + + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " set;\n" + " get;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " get;\n" + " set;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " get;\n" + " init;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " set\n" + " {\n" + " val = value;\n" + " }\n" + " get\n" + " {\n" + " return value;\n" + " }\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " init\n" + " {\n" + " val = value;\n" + " }\n" + " get\n" + " {\n" + " return value;\n" + " }\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " get;\n" + " set\n" + " {\n" + " val = value;\n" + " }\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " get;\n" + " init\n" + " {\n" + " val = value;\n" + " }\n" + " }\n" + "}", + Style); + + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " private set;\n" + " get;\n" + " }\n" + "}", + Style); + + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " set;\n" + " internal get;\n" + " }\n" + "}", + Style); + + verifyFormat("class A\n" + "{\n" + " string Bar6\n" + " {\n" + " set;\n" + " internal get\n" + " {\n" + " return value;\n" + " };\n" + " }\n" + "}", + Style); + + verifyFormat("class A\n" + "{\n" + " string Bar5\n" + " {\n" + " internal get\n" + " {\n" + " return value;\n" + " };\n" + " set;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " internal set;\n" + " get\n" + " {\n" + " return value;\n" + " };\n" + " }\n" + "}", + Style); + + Style.BraceWrapping.AfterCSharpProperty = true; + Style.AllowShortCSharpPropertiesOnASingleLine = false; + Style.AlwaysBreakBetweenShortCSharpProperties = false; + Style.BraceWrapping.AfterFunction = true; + + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " set; get;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " get; set;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " init; get;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " internal set; get;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " set; protected get;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " set;\n" + " protected get\n" + " {\n" + " return value;\n" + " }\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar\n" + " {\n" + " public get\n" + " {\n" + " return value;\n" + " }\n" + " set;\n" + " }\n" + "}", + Style); + + Style.BraceWrapping.AfterCSharpProperty = false; + Style.AllowShortCSharpPropertiesOnASingleLine = false; + Style.AlwaysBreakBetweenShortCSharpProperties = false; + Style.BraceWrapping.AfterFunction = false; + + verifyFormat("class A\n" + "{\n" + " string Bar1 {\n" + " set; get;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar1 {\n" + " get; set;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar1 {\n" + " init; get;\n" + " }\n" + "}", + Style); + + verifyFormat("class A\n" + "{\n" + " string Bar2 {\n" + " public set; get;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar2 {\n" + " set; private get;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar3 {\n" + " set { value = 123 }\n" + " get;\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar4 {\n" + " get;\n" + " set { value = 123 }\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar4 {\n" + " private get;\n" + " set { value = 123 }\n" + " }\n" + "}", + Style); + verifyFormat("class A\n" + "{\n" + " string Bar4 {\n" + " get;\n" + " private set { value = 123 }\n" + " }\n" + "}", + Style); +} + } // namespace format } // end namespace clang